kb-text-shape (empty) → 0.1.0.0
raw patch · 24 files changed
+37683/−0 lines, 24 filesdep +basedep +bytestringdep +containers
Dependencies added: base, bytestring, containers, kb-text-shape, text, unliftio
Files
- CHANGELOG.md +11/−0
- LICENSE +26/−0
- README.md +50/−0
- bench/Bench.hs +129/−0
- cbits/kb_text_shape.c +76/−0
- cbits/kb_text_shape.h +3699/−0
- cbits/kb_text_shape.inc +26055/−0
- kb-text-shape.cabal +157/−0
- src/KB/Text/Shape.hs +322/−0
- src/KB/Text/Shape/FFI/API/Context.hsc +201/−0
- src/KB/Text/Shape/FFI/API/Direct.hsc +243/−0
- src/KB/Text/Shape/FFI/API/Other.hsc +65/−0
- src/KB/Text/Shape/FFI/API/Segmentation.hsc +111/−0
- src/KB/Text/Shape/FFI/Allocator.hsc +99/−0
- src/KB/Text/Shape/FFI/Enums.hsc +434/−0
- src/KB/Text/Shape/FFI/Enums/FeatureTag.hsc +1247/−0
- src/KB/Text/Shape/FFI/Enums/Language.hsc +2759/−0
- src/KB/Text/Shape/FFI/Enums/Script.hsc +703/−0
- src/KB/Text/Shape/FFI/Flags.hsc +340/−0
- src/KB/Text/Shape/FFI/Handles.hsc +41/−0
- src/KB/Text/Shape/FFI/Iterators.hsc +21/−0
- src/KB/Text/Shape/FFI/Structs.hsc +484/−0
- src/KB/Text/Shape/Font.hs +180/−0
- test/Spec.hs +230/−0
+ CHANGELOG.md view
@@ -0,0 +1,11 @@+# Changelog for `kb-text-shape`++All notable changes to this project will be documented in this file.++The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),+and this project adheres to the+[Haskell Package Versioning Policy](https://pvp.haskell.org/).++## Unreleased++## 0.1.0.0 - YYYY-MM-DD
+ LICENSE view
@@ -0,0 +1,26 @@+Copyright 2025 IC Rainbow++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.++3. Neither the name of the copyright holder nor the names of its contributors+ may be used to endorse or promote products derived from this software+ without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+ README.md view
@@ -0,0 +1,50 @@+# kb-text-shape++Haskell wrapper for the `kb_text_shape.h` unicode segmentation and shaping library.++[kb\_text\_shape.h]: https://github.com/JimmyLefevre/kb/blob/main/kb_text_shape.h++> ```+> Your text A Text runs with B Sequence of glyphs C+> (Probably ------------> uniform direction ------------> ready to rasterize ------------> Pixels+> UTF-8) and script+> ```+> We call arrow A text segmentation, arrow B text shaping, and arrow C rasterization.+> This library does A and B.++```haskell+import KB.Text.Shape where qualified as TextShape++main = do+ TextShape.withContext \ctx -> do+ _fallback <- TextShape.pushFontFromFile ctx "test/NotoSans-Regular.ttf" 0+ _main <- TextShape.pushFontFromFile ctx "test/Ubuntu-R.ttf" 0+ results <- TextShape.run ctx do+ TextShape.text_ "A bunch of characters"+ TextShape.char_ '!'+ forM_ results \(run, glyphs) ->+ forM_ glyphs \glyph ->+ print (run.font, glyph.id, glyph.gpos.advanceX)+```++## Font blobs++The library has an internal "blob" format for the pre-processed font data for leaner files and faster loading.++```haskell+import KB.Text.Shape.Font qualified as Font++main = do+ ttfData <- ByteString.readFile "test/Ubuntu-R.ttf"+ putStrLn $ "Distilling " <> show (ByteString.length ttfData `div` 1024) <> "Kb of TTF"+ blobData <- Font.extractBlob ttfData 0+ putStrLn $ "Distilled into " <> show (ByteString.length blobData `div` 1024) <> "Kb blob"+ ByteString.writeFile "test/Ubuntu-R.kbts" blobData+```++The savings are modest, but can be improved even further with compression.++```+Distilling 1047Kb of TTF+Distilled into 618Kb blob+```
+ bench/Bench.hs view
@@ -0,0 +1,129 @@+{-# LANGUAGE OverloadedRecordDot #-}++import Control.Monad+import Data.Char+import Foreign+import Prelude hiding (id)++import UnliftIO.Async (pooledForConcurrently_)+import Control.Exception (bracket)+import Data.ByteString qualified as ByteString+import Data.Text (Text)+import Data.Text qualified as Text++import KB.Text.Shape.FFI.API.Direct qualified as ShapeDirect+import KB.Text.Shape.FFI.Allocator (Allocator)+import KB.Text.Shape.FFI.Allocator qualified as Allocator+import KB.Text.Shape.FFI.Enums qualified as Enums+import KB.Text.Shape.FFI.Handles qualified as Handles+import KB.Text.Shape.FFI.Iterators qualified as Iterators+import KB.Text.Shape.FFI.Structs qualified as Structs++import KB.Text.Shape qualified as TextShape+import KB.Text.Shape.Font qualified as TextShape++testFontTtf :: FilePath+testFontTtf = "test/Ubuntu-R.ttf"++testFontBlob :: FilePath+testFontBlob = "test/Ubuntu-R.blob"++testText :: Text+testText = "Hello, ሰላም።, שלמלך, नमस्ते world!"++testCodepoints :: [Char]+testCodepoints = Text.unpack testText++main :: IO ()+main = do+ mainBurnContext+ mainBurnDirect++mainBurnContext :: IO ()+mainBurnContext = do+ pooledForConcurrently_ [0..100] $ \t -> TextShape.withContext \ctx -> do+ putStrLn $ "Batch " <> show t <> " starting"+ _font <- TextShape.pushFontFromFile ctx testFontBlob 0+ forM_ [0 :: Int .. 10000] \ix -> do+ !_ <- length . show <$> TextShape.run ctx (TextShape.text_ testText)+ pure ()++mainBurnDirect :: IO ()+mainBurnDirect = do+ fontData <- ByteString.readFile testFontBlob+ font <- TextShape.createFont fontData 0+ pooledForConcurrently_ [0 :: Int .. 100000] \ix -> do+ !_ <- length . show <$> oneshot font 42 testCodepoints+ pure ()+ TextShape.destroyFont font+ fontData `seq`pure ()++oneshot :: TextShape.FontData -> Int -> [Char] -> IO [TextShape.Glyph]+oneshot fontData userId codepoints =+ TextShape.withFontData fontData \font ->+ withShapeConfig font script language \shapeConfig ->+ withGlyphStorage \glyphStoragePtr -> do+ withGlyphConfig \glyphConfig ->+ pushCodepoints font glyphStoragePtr glyphConfig userId codepoints+ shapeDirect shapeConfig glyphStoragePtr+ where+ script = Enums.SCRIPT_DONT_KNOW+ language = Enums.LANGUAGE_DONT_KNOW++withShapeConfig font script language =+ bracket+ (ShapeDirect.kbts_CreateShapeConfig font script language nullFunPtr nullPtr)+ ShapeDirect.kbts_DestroyShapeConfig++withGlyphStorage :: (Ptr Structs.GlyphStorage -> IO b) -> IO b+withGlyphStorage action = alloca @Structs.GlyphStorage \ptr -> do+ fillBytes ptr 0 (sizeOf (undefined :: Structs.GlyphStorage))+ action ptr++withGlyphConfig :: (Handles.GlyphConfig -> IO c) -> IO c+withGlyphConfig =+ bracket+ (ShapeDirect.kbts_CreateGlyphConfig nullPtr 0 nullFunPtr nullPtr)+ ShapeDirect.kbts_DestroyGlyphConfig++pushCodepoints :: (Foldable t, Integral a) => TextShape.Font -> Ptr Structs.GlyphStorage -> Handles.GlyphConfig -> a -> t Char -> IO ()+pushCodepoints font glyphStoragePtr glyphConfig userId = mapM_ \codepoint ->+ ShapeDirect.kbts_PushGlyph+ glyphStoragePtr+ font+ (fromIntegral $ ord codepoint)+ glyphConfig+ (fromIntegral userId)++shapeDirect :: Handles.ShapeConfig -> Ptr Structs.GlyphStorage -> IO [TextShape.Glyph]+shapeDirect shapeConfig glyphStoragePtr =+ alloca \glyphItPtr -> do+ !err <- ShapeDirect.kbts_ShapeDirect+ shapeConfig+ glyphStoragePtr+ Enums.DIRECTION_DONT_KNOW+ nullFunPtr+ nullPtr+ glyphItPtr+ when (err /= Enums.SHAPE_ERROR_NONE) $+ error $ show err+ alloca \glyphOutPtr ->+ iterateGlyphs glyphOutPtr glyphItPtr++-- some copypasta from unexported parts++iterateGlyphs :: Ptr (Ptr Structs.Glyph) -> Ptr Structs.GlyphIterator -> IO [TextShape.Glyph]+iterateGlyphs glyphOutPtr it = stepWhile step fetch+ where+ step = (/= 0) <$> Iterators.kbts_GlyphIteratorNext it glyphOutPtr+ fetch = do+ peek glyphOutPtr >>= peek >>= TextShape.stripGlyph++stepWhile :: Monad m => m Bool -> m a -> m [a]+stepWhile step fetch = do+ result <- step+ if result then do+ x <- fetch+ (x :) <$> stepWhile step fetch+ else+ pure []
+ cbits/kb_text_shape.c view
@@ -0,0 +1,76 @@+#include <stdint.h>++#ifdef TRACE_BLOCKS+#define KBTS_INSTRUMENT_BLOCK_BEGIN(Name) printf("<%s>\n", #Name)+#define KBTS_INSTRUMENT_BLOCK_END(Name) printf("</%s>\n", #Name)+#define KBTS_INSTRUMENT_FUNCTION_BEGIN+#define KBTS_INSTRUMENT_FUNCTION_END+#endif++#include "kb_text_shape.h"+#include "kb_text_shape.inc"++void hs_ShapeCurrentCodepointsIterator(kbts_shape_context *Context, kbts_shape_codepoint_iterator *It)+{+ *It = kbts__InputCodepointIterator(Context, 0, Context->InputCodepointCount);+}++void hs_CodepointToGlyph(kbts_font *Font, int Codepoint, kbts_glyph_config *Config, int UserId, kbts_glyph *Glyph)+{+ *Glyph = kbts_CodepointToGlyph(Font, Codepoint, Config, UserId);+}++void hs_ActiveGlyphIterator(kbts_glyph_storage *Storage, kbts_glyph_iterator *It) {+ *It = kbts_ActiveGlyphIterator(Storage);+}++kbts_load_font_error hs_FontFromFile(const char *FileName, int FontIndex, kbts_allocator_function *Allocator, void *AllocatorData, void **FileData, int *FileSize_, kbts_font *Font) {+ *Font = kbts_FontFromFile(FileName, FontIndex, Allocator, AllocatorData, FileData, FileSize_);+ return Font->Error;+}++kbts_load_font_error hs_FontFromMemory(void *FileData, int FileSize, int FontIndex, kbts_allocator_function *Allocator, void *AllocatorData, kbts_font *Font) {+ *Font = kbts_FontFromMemory(FileData, FileSize, FontIndex, Allocator, AllocatorData);+ return Font->Error;+}++uint16_t hs_GetCapHeight(kbts_font *Font) {+ if (!Font || !Font->Blob) return 0;++ kbts_blob_header *Header = Font->Blob;+ kbts_blob_table *TableEntry = &Header->Tables[KBTS_BLOB_TABLE_ID_OS2];+ if (TableEntry->Length < 90) return 0;++ uint8_t *BlobStart = (uint8_t *)Header;+ uint8_t *TableData = BlobStart + TableEntry->OffsetFromStartOfFile;++ uint16_t CapHeight;+ memcpy(&CapHeight, TableData + 88, sizeof(uint16_t));++ return CapHeight;+}+++uint16_t hs_GetUnitsPerEm(kbts_font *Font) {+ if (!Font || !Font->Blob) return 0;++ kbts_blob_header *Header = Font->Blob;++ // Access the entry for the 'head' table+ kbts_blob_table *HeadTableEntry = &Header->Tables[KBTS_BLOB_TABLE_ID_HEAD];++ // Ensure the table exists and is large enough (min length is usually 54 bytes)+ if (HeadTableEntry->Length < 20) return 0;++ // Calculate the pointer to the table data+ // Note: Offsets are relative to the start of the blob header+ uint8_t *BlobStart = (uint8_t *)Header;+ uint8_t *HeadTableData = BlobStart + HeadTableEntry->OffsetFromStartOfFile;++ // The library stores the Blob data in Native Endian.+ // We use memcpy to safely read the 16-bit integer without violating alignment rules.+ uint16_t UnitsPerEm;+ memcpy(&UnitsPerEm, HeadTableData + 18, sizeof(uint16_t));++ return UnitsPerEm;+}
+ cbits/kb_text_shape.h view
@@ -0,0 +1,3699 @@+/* kb_text_shape - v2.06 - text segmentation and shaping+ by Jimmy Lefevre++ SECURITY+ This library provides NO SECURITY GUARANTEE whatsoever.+ DO NOT use it on untrusted font files.++ WHAT DOES THIS LIBRARY DO?+ Before computers had monitors, the main way of inspecting the output of a command+ was to print it out on real paper. When monitors appeared, most computer graphics+ were text-based, meaning the display was arranged in a hardcoded grid in which each+ cell could hold one of several hardcoded characters. As simple as it is, this kind+ of text handling is sufficient for displaying almost any document written in the+ Latin alphabet and a few other writing systems that happen to fit particularly well+ on a grid, like Chinese and Japanese.+ Handwritten Latin characters do not all have the same width, however. As computers+ became more powerful, glyphs started having different widths to fit better together.+ After that came kerning, which allows for packing glyphs closer together in pairs.+ This is, of course, N-squared in the number of glyphs you want to handle, but this+ is fine for the Latin alphabet, because there really aren't that many glyphs.+ This is where TrueType stops: it is a good and simple, format for displaying text+ using the Latin alphabet or writing systems that happen to work similarly to it.+ All is well and good.++ What about the rest of the writing systems?++ Arabic is a cursive writing system. Much like when we write cursive ourselves, the+ letters need to join together visually. Furthermore, a given letter in Arabic has+ a different appearance depending on whether it is the first letter of a word, the+ last letter of a word, or in the middle, and Unicode does not differenciate between+ any of these. Also, Arabic features a beautiful set of marks that attach to letters,+ much like accents in the Latin alphabet. You would usually want to align these marks+ in some way depending on which other marks are present in the immediate vicinity.++ Indic scripts, like Devanagari, have even less in common with Latin than Arabic does.++ To try to support the plethora of writing systems out there, OpenType was introduced.+ OpenType fonts contain rules that allow modifying a sequence of glyphs through pattern+ matching. These rules can modify both the content of the sequence (ligatures replace+ multiple glyphs with a single one, for instance) and its visual appearance by e.g.+ attaching marks to letters. This is the meat of text shaping.++ OpenType rules have limitations, though. They don't work with mixed direction text,+ because, when going from one text direction to the other, there is a visual jump that+ breaks pattern matching.++ To illustrate, the logical string "0123456789" might have a display order like this:++ 01234 765 89+ ^LTR ^RTL ^LTR continued++ As you can see, there is a visual jump from 4 all the way to 5, and similarly from+ 7 to 8.+ This kind of discontinuity cannot work with OpenType rules, which want to work with+ "neighboring" glyphs in the visual sense.++ OpenType rules don't work with mixed script text, either. They are designed to work with+ a single writing system, and ideally a single language. A typographic rule that is correct+ in writing system A might not be in writing system B, and vice versa.++ So, for all of these reasons, we need to split our text before sending it to the shaper.+ This is what the text processing pipeline looks like:++ Your text A Text runs with B Sequence of glyphs C+ (Probably ------------> uniform direction ------------> ready to rasterize ------------> Pixels+ UTF-8) and script++ We call arrow A text segmentation, arrow B text shaping, and arrow C rasterization.+ This library does A and B.++ FEATURE OVERVIEW+ This library provides:+ - Unicode segmentation+ LTR/RTL breaking+ Script breaking+ Line breaking+ Word breaking+ Grapheme breaking+ - OpenType text shaping+ Open and parse TTF and OTF fonts+ Apply OpenType features such as ligatures and contextual typographic rules+ All OpenType shapers are supported, which means most languages in the world are supported+ (see LANGUAGE_SUPPORT for known non-supported cases)++ COMPILING & LINKING+ This library uses declare-anywhere, so it will not compile as C89/VC6 C.++ In one C/C++ file that #includes this file, do this:+ #define KB_TEXT_SHAPE_IMPLEMENTATION+ before the #include. That will create the implementation in that file.++ If you also do this:+ #define KB_TEXT_SHAPE_STATIC+ then all functions will be declared as static.++ If you do this:+ #define KB_TEXT_SHAPE_NO_CRT+ then we do not use the C runtime library.+ In that case, these functions are compiled out:+ kbts_ShapePushFontFromFile()+ kbts_FontFromFile()+ Additionally, there are some functions that you will want to #define yourself:+ KBTS_MEMSET+ defaults to memset otherwise.+ KBTS_MEMCPY+ defaults to memcpy otherwise.+ You can redefine the default allocator by redefining these:+ KBTS_MALLOC(AllocatorData, Size)+ defaults to 0 if KB_TEXT_SHAPE_NO_CRT is defined,+ defaults to malloc(Size) otherwise.+ KBTS_FREE(AllocatorData, Pointer)+ defaults to a no-op if KB_TEXT_SHAPE_NO_CRT is defined,+ defaults to free(Pointer) otherwise.+ In other words,+ if you do not redefine the default allocator, and you #define KB_TEXT_SHAPE_NO_CRT,+ then the default allocator always returns 0.++ EXAMPLES+ Basic+ kbts_shape_context *Context = kbts_CreateShapeContext(0, 0);+ kbts_ShapePushFontFromFile(Context, "myfont.ttf", 0);++ kbts_ShapeBegin(Context, KBTS_DIRECTION_DONT_KNOW, KBTS_LANGUAGE_DONT_KNOW);+ kbts_ShapeUtf8(Context, "Let's shape something!", sizeof("Let's shape something!") - 1, KBTS_USER_ID_GENERATION_MODE_CODEPOINT_INDEX);+ kbts_ShapeEnd(Context);++ // Layout runs naively left to right.+ kbts_run Run;+ int CursorX = 0, CursorY = 0;+ while(kbts_ShapeRun(Context, &Run))+ {+ kbts_glyph *Glyph;+ while(kbts_GlyphIteratorNext(&Run.Glyphs, &Glyph))+ {+ int GlyphX = CursorX + Glyph->OffsetX;+ int GlyphY = CursorY + Glyph->OffsetY;++ DisplayGlyph(Glyph->Id, GlyphX, GlyphY);++ CursorX += Glyph->AdvanceX;+ CursorY += Glyph->AdvanceY;+ }+ }++ Font collections+ void *FontData;+ int FontSize;+ kbts_font Font = kbts_FontFromFile("myfonts.ttc", 0, 0, 0, &FontData, &FontSize);++ kbts_ShapePushFont(Context, &Font);++ int FontCount = kbts_FontCount(FontData, FontSize);+ for(int FontIndex = 1; FontIndex < FontCount; ++FontIndex)+ {+ kbts_ShapePushFontFromMemory(Context, FontData, FontSize, FontIndex);+ }++ Feature control+ kbts_ShapeBegin(Context, KBTS_DIRECTION_DONT_KNOW, KBTS_LANGUAGE_DONT_KNOW);++ kbts_ShapePushFeature(Context, KBTS_FEATURE_TAG_kern, 0);+ kbts_ShapeUtf8(Context, "Without kerning", sizeof("Without kerning") - 1, KBTS_USER_ID_GENERATION_MODE_CODEPOINT_INDEX);+ kbts_ShapePopFeature(Context, KBTS_FEATURE_TAG_kern);++ kbts_ShapeUtf8(Context, "With kerning", sizeof("With kerning") - 1, KBTS_USER_ID_GENERATION_MODE_CODEPOINT_INDEX);++ kbts_ShapeEnd(Context);++ @Todo: Write more examples++ API+ The shaping API is broken down into two parts: the context API and the direct API.++ The context API is the higher-level API of the two and is meant to be the default+ API.+ It exposes an immediate-mode, procedural interface somewhat inspired by Dear Imgui+ and covers most of the functionality present in the library. It notably includes+ automatic segmentation into paragraphs and runs, shaping, and font fallback.++ The direct API, in contrast, is all of the tools you can use to directly manage and+ manipulate shaping data. With it, you can interact directly with the lower-level+ parts of the library, giving you very granular control. It is also very explicit+ about memory. As a result, it is also a lot more verbose than the context API.++ The library also contains several miscellaneous utility functions that are not+ obviously part of any of the two aforementioned APIs.+++ In the documentation below, all functions (as well as some structs/enums) are+ marked with "search tags".+ As an example, this hypothetical function:++ int kbts_Foo(int X);++ Will be presented like this:++ :kbts_Foo+ :Foo+ int kbts_Foo(int X);++ Allowing you to easily search for its documentation by searching for either ":Foo"+ or ":kbts_Foo".++ MEMORY MANAGEMENT+ kb_text_shape takes manual memory management seriously, and tries to give the user as much+ control over memory as possible.++ Whenever it is possible for you to pass your own buffer into a function, we allow it.+ Whenever it is not possible, we allow specifying a custom allocator.+ An allocator is simply a function that manages memory:++ :kbts_allocator_function+ :allocator_function+ typedef void kbts_allocator_function(void *Data, kbts_allocator_op *Op);+ [Data] the custom data pointer you passed in along with your allocator.+ [Op] the memory request. It is of this type:++ :kbts_allocator_op+ :allocator_op+ typedef struct kbts_allocator_op+ {+ kbts_allocator_op_kind Kind;++ union+ {+ kbts_allocator_op_allocate Allocate;+ kbts_allocator_op_free Free;+ };+ } kbts_allocator_op;++ And the possible op kinds are:+ KBTS_ALLOCATOR_OP_KIND_ALLOCATE+ KBTS_ALLOCATOR_OP_KIND_FREE++ ALLOCATE expects you to fill in Op->Allocate.Pointer.+ The allocation does not need to be aligned.+ FREE expects you to free Op->Free.Pointer.++ THE CONTEXT API+ CONTEXT:CREATION+ :kbts_SizeOfShapeContext+ :SizeOfShapeContext+ int kbts_SizeOfShapeContext()+ Tells you how big of a buffer you need to provide to kbts_PlaceShapeContext.++ :kbts_PlaceShapeContext+ :PlaceShapeContext+ kbts_shape_context *kbts_PlaceShapeContext(kbts_allocator_function *Allocator, void *AllocatorData, void *Memory)+ Places a context at Memory and initializes it.+ [Allocator] will be used for subsequent allocations.++ :kbts_PlaceShapeContextFixedMemory+ :PlaceShapeContextFixedMemory+ kbts_shape_context *kbts_PlaceShapeContextFixedMemory(void *Memory, int Size)+ Places a context at Memory and initializes it.+ This context will only use the [Size] bytes located at [Memory] for its allocations.++ :kbts_CreateShapeContext+ :CreateShapeContext+ kbts_shape_context *kbts_CreateShapeContext(kbts_allocator_function *Allocator, void *AllocatorData)+ Allocates a context using [Allocator] and initializes it.++ :kbts_DestroyShapeContext+ :DestroyShapeContext+ void kbts_DestroyShapeContext(kbts_shape_context *Context)+ Frees all context memory.+ If the Context was allocated by kbts_CreateShapeContext, then it is also freed.++ CONTEXT:FONT HANDLING+ The context is capable of managing multiple fonts through a font stack.+ The font stack will hold references to all fonts in use by the context. Whenever+ you try to shape some text, the context will check to see if it is supported by+ the font at the top of the stack. If it is not, it will try the next font down,+ and so on, until all fonts have been tried. As such, you should push your fallback+ fonts first, and your preferred fonts last.++ :kbts_ShapePushFontFromFile+ :ShapePushFontFromFile+ kbts_font *kbts_ShapePushFontFromFile(kbts_shape_context *Context, const char *FileName, int FontIndex)+ (This function is not available if KB_TEXT_SHAPE_NO_CRT is defined.)++ Opens the file corresponding to [FileName], parses the [FontIndex]th font+ within it, and, if successful, pushes the result onto the stack.++ A [return value] of 0 could mean that the stack is out of space (see+ KBTS_CONTEXT_MAX_FONT_COUNT), that the file could not be found or opened,+ or that the parse has failed.++ :kbts_ShapePushFontFromMemory+ :ShapePushFontFromMemory+ kbts_font *kbts_ShapePushFontFromMemory(kbts_shape_context *Context, void *Memory, int Size, int FontIndex)+ Parses the [FontIndex]th font in [Memory] and pushes the result to the font+ stack.++ A [return value] of 0 could mean that the stack is out of space (see+ KBTS_CONTEXT_MAX_FONT_COUNT) or that the font could not be parsed.++ :kbts_ShapePushFont+ :ShapePushFont+ kbts_font *kbts_ShapePushFont(kbts_shape_context *Context, kbts_font *Font)+ Pushes the pre-parsed [Font] onto the stack.++ A [return value] of 0 means that the stack has run out of space (see+ KBTS_CONTEXT_MAX_FONT_COUNT).++ :kbts_ShapePopFont+ :ShapePopFont+ kbts_font *kbts_ShapePopFont(kbts_shape_context *Context)+ Removes the topmost font from the stack.++ A [return value] of 0 means that there is no font to remove.+ A non-null [return value] is the original font pointer that was pushed.++ If the context allocated the font itself, using kbts_ShapePushFontFromFile or+ kbts_ShapePushFontFromMemory, then the pointer is still returned, but it points to+ freed memory.++ CONTEXT:SHAPING+ :kbts_ShapeBegin+ :ShapeBegin+ void kbts_ShapeBegin(kbts_shape_context *Context, kbts_direction ParagraphDirection, kbts_language Language)+ Begins a shaping pass.++ [ParagraphDirection] is sometimes called the "document direction". It can significantly+ affect segmentation. Bidirectionality in text works like a stack: the default direction+ is at the bottom of the stack, and, sometimes, text can _temporarily_ take a different+ direction. In the end, though, it will always go back to the document direction.++ To illustrate, a period followed by a space ". " typically ends up resetting the current+ direction to the paragraph direction. This means that, if my paragraph direction is+ left-to-right, and I am shaping Arabic text, then each Arabic sentence will be+ right-to-left, but the sentences themselves will be sequenced left-to-right. If+ [ParagraphDirection] is KBTS_DIRECTION_DONT_KNOW, then the context takes the first+ directional hint in the text as the paragraph direction.++ [Language] is used to select which font rules are used. Knowing this allows access to+ language-specific typographical features. If [Language] is KBTS_LANGUAGE_DONT_KNOW, then+ the default, language-agnostic font rules are used.++ :kbts_ShapeEnd+ :ShapeEnd+ void kbts_ShapeEnd(kbts_shape_context *Context)+ Ends a shaping pass.++ This means you are done providing input to the context, and, in turn, that+ you can start getting results from it with kbts_ShapeRun().++ :kbts_ShapeRun+ :ShapeRun+ int kbts_ShapeRun(kbts_shape_context *Context, kbts_run *Run)+ Once you've called kbts_ShapeEnd, you can get the resulting runs by calling this+ function repeatedly.++ !!! CAREFUL !!! Memory is reused from one run to the next, so you cannot+ trivially store [Run] and reuse it later. Instead, you should traverse the+ glyphs using the iterator provided in Run.Glyphs and extract whatever data+ you need before calling kbts_ShapeRun again.++ The [return value] is non-zero if a run was shaped.+ When there is no text left to shape, the [return value] is 0.++ kbts_ShapeEnd(Context);+ kbts_run Run;+ while(kbts_ShapeRun(Context, &Run))+ {+ // Handle Run+ }++ :kbts_ShapePushFeature+ :ShapePushFeature+ void kbts_ShapePushFeature(kbts_shape_context *Context, kbts_u32 FeatureTag, int Value)+ The context has a feature stack that allows you to manipulate font features hierarchically.+ When you give text to the context, it will apply all feature overrides that are on the+ stack at the time.+ If two feature overrides use the same tag, then only the latest one, i.e. the one higher+ in the stack, is applied.++ :kbts_ShapePopFeature+ :ShapePopFeature+ int kbts_ShapePopFeature(kbts_shape_context *Context, kbts_u32 FeatureTag)+ Removes the latest feature override with tag [FeatureTag].+ The [return value] is non-zero if an override was found and removed, 0 if not.++ :kbts_ShapeCodepointWithUserId+ :ShapeCodepointWithUserId+ void kbts_ShapeCodepointWithUserId(kbts_shape_context *Context, int Codepoint, int UserId)+ Inputs a codepoint to shape.+ [Codepoint] is a Unicode codepoint.+ [UserId] is an arbitrary identifier that you will get back when reading the results.+ This is often some kind of index into the input text so that you can perform hit-testing.+ If an automatic codepoint index is fine for you, consider using kbts_ShapeCodepoint.++ :kbts_ShapeCodepoint+ :ShapeCodepoint+ void kbts_ShapeCodepoint(kbts_shape_context *Context, int Codepoint)+ Inputs a codepoint to shape.++ The codepoint's user ID will be an implicit codepoint index assigned by the+ context.++ :kbts_ShapeUtf32WithUserId+ :ShapeUtf32WithUserId+ void kbts_ShapeUtf32WithUserId(kbts_shape_context *Context,+ int *Utf32, int Length,+ int UserId, int UserIdIncrement);+ Inputs a block of UTF-32 text to shape.++ User IDs for each codepoint start at [UserId] and increment by [UserIdIncrement]+ for every codepoint.++ :kbts_ShapeUtf32+ :ShapeUtf32+ void kbts_ShapeUtf32(kbts_shape_context *Context, int *Utf32, int Length)+ Same as kbts_ShapeUtf8WithUserId, but using the context's implicit user ID counter.++ :kbts_ShapeUtf8WithUserId+ :ShapeUtf8WithUserId+ void kbts_ShapeUtf8WithUserId(kbts_shape_context *Context,+ const char *Utf8, int Length,+ int UserId, kbts_user_id_generation_mode UserIdGenerationMode);+ Inputs a block of UTF-8 text to shape.++ User IDs for the corresponding codepoints start at [UserId].+ If [UserIdGenerationMode] is KBTS_USER_ID_GENERATION_MODE_CODEPOINT_INDEX,+ each codepoint will increment the user ID by 1.+ If [UserIdGenerationMode] is KBTS_USER_ID_GENERATION_MODE_CODEPOINT_INDEX,+ each codepoint will increment the user ID by the length of its encoding in+ UTF-8.++ :kbts_ShapeUtf8+ :ShapeUtf8+ void kbts_ShapeUtf8(kbts_shape_context *Context,+ const char *Utf8, int Length,+ kbts_user_id_generation_mode UserIdGenerationMode)+ Same as kbts_ShapeUtf8WithUserId, but using the context's implicit user ID+ counter.++ User IDs for the corresponding codepoints start at the context's implicit+ user ID counter.+ If [UserIdGenerationMode] is KBTS_USER_ID_GENERATION_MODE_CODEPOINT_INDEX,+ each codepoint will increment the user ID by 1.+ If [UserIdGenerationMode] is KBTS_USER_ID_GENERATION_MODE_CODEPOINT_INDEX,+ each codepoint will increment the user ID by the length of its encoding in+ bytes in UTF-8.++ :kbts_ShapeCurrentCodepointsIterator+ :ShapeCurrentCodepointsIterator+ kbts_shape_codepoint_iterator kbts_ShapeCurrentCodepointsIterator(kbts_shape_context *Context)+ The [return value] is an iterator that goes over all of the codepoints fed to+ [Context] so far.++ These codepoints are tagged with user IDs, segmentation info and more. See+ the definition of kbts_shape_codepoint for details.++ !!! WARNING !!!+ Remember that segmentation is buffered, so, until you call kbts_ShapeEnd,+ some codepoints might not be completely filled in yet!++ Call kbts_ShapeCodepointIteratorNext repeatedly to loop through the+ corresponding codepoints.++ :kbts_ShapeCodepointIteratorIsValid+ :ShapeCodepointIteratorIsValid+ int kbts_ShapeCodepointIteratorIsValid(kbts_shape_codepoint_iterator *It)+ The [return value] is non-zero if there is still a codepoint to iterate,+ zero if not.++ :kbts_ShapeCodepointIteratorNext+ :ShapeCodepointIteratorNext+ int kbts_ShapeCodepointIteratorNext(kbts_shape_codepoint_iterator *It, kbts_shape_codepoint *Codepoint, int *CodepointIndex)+ Gets the next codepoint from the context [It] was initialized from and writes+ it to [Codepoint].++ If [CodepointIndex] is non-zero, then it is filled with [Codepoint]'s index.++ The [return value] is non-zero if a codepoint was found, 0 if not.++ :kbts_ShapeGetShapeCodepoint+ :ShapeGetShapeCodepoint+ int kbts_ShapeGetShapeCodepoint(kbts_shape_context *Context, int CodepointIndex, kbts_shape_codepoint *Codepoint)+ Gets the [CodepointIndex]th codepoint from [Context] and writes it to+ [Codepoint].++ If you are reading glyphs back from the context, then you can use the+ UserIdOrCodepointIndex field of kbts_glyph here.++ !!! WARNING !!!+ When using the context API, UserIdOrCodepointIndex will _always_ be a+ codepoint index. To get your original user ID, you need to do:++ kbts_shape_codepoint ShapeCodepoint;+ kbts_ShapeGetShapeCodepoint(Context, Glyph->UserIdOrCodepointIndex, &ShapeCodepoint);+ int MyUserId = ShapeCodepoint.UserId;++ The [return value] is non-zero if [CodepointIndex] is in-bounds, 0 if not.++ CONTEXT:MISCELLANEOUS+ :kbts_ShapeError+ :ShapeError+ kbts_shape_error kbts_ShapeError(kbts_shape_context *Context);+ Get the first error that occurred on [Context].++ Once a context is tagged with an error, most operations on it will do nothing.+ Obviously, you can always destroy it.++ :kbts_ShapeManualBreak+ :ShapeManualBreak+ void kbts_ShapeManualBreak(kbts_shape_context *Context);+ Forces a run break at the current position in the Context.++ This will flush the current segmentation state just like an end-of-text would,+ and restart it as if it was at a start-of-text.++ This will also generate a KBTS_BREAK_FLAG_MANUAL at the current position.++ You do not need to be in manual break mode for this function to work.++ :kbts_ShapeBeginManualRuns+ :ShapeBeginManualRuns+ void kbts_ShapeBeginManualRuns(kbts_shape_context *Context);+ Disables the context's automatic segmentation, and enters a manual break mode.++ :kbts_ShapeNextManualRun+ :ShapeNextManualRun+ void kbts_ShapeNextManualRun(kbts_shape_context *Context, kbts_direction Direction, kbts_script Script);+ Add a run break at the current place in the input stream.++ Since the context's segmentation is disabled, it cannot know which direction+ and script to use, so you need to provide them with [Direction] and [Script].++ Outside of manual break mode, this function is a no-op.++ :kbts_ShapeEndManualRuns+ :ShapeEndManualRuns+ void kbts_ShapeEndManualRuns(kbts_shape_context *Context);+ Ends manual break mode and re-enables the context's automatic segmentation.++ Note that this will force natural break barriers too, just like an end-of-text+ would.++ Outside of manual break mode, this function is a no-op.++ DIRECT SHAPING API+ When trying to shape things yourself, there are four main pieces of state you will need:+ - Font data (kbts_font)+ - A shaping configuration (kbts_shape_config)+ A shaping configuration holds a bunch of precomputed data for a given combination of+ font, script and language.+ You can think of it as a pipeline state in a modern graphics API.+ In practice, you are only ever shaping text with a single active configuration.+ - Glyph storage (kbts_glyph_storage)+ Glyph storage fills two roles: it allocates and holds glyph data, and it also manages+ a set of active glyphs.+ The active glyph set part is used by the library. As a user, you only need to care+ about the memory allocation part.+ - Scratch memory+ Unfortunately, shaping can have a very unpredictable memory footprint, so all shaping+ operations require some amount of scratch space that we cannot compute beforehand.++ The central function to call is this:++ :kbts_ShapeDirect+ :ShapeDirect+ kbts_shape_error kbts_ShapeDirect(kbts_shape_config *Config, kbts_glyph_storage *Storage,+ kbts_direction RunDirection,+ kbts_allocator_function *Allocator, void *AllocatorData,+ kbts_glyph_iterator *Output)+ [RunDirection] is the direction of the specific run being shaped.+ If the [return value] is KBTS_SHAPE_ERROR_NONE, then the shaping operation+ completed successfully.++ Shaping output is returned in [Output]. You can go through the resulting glyphs+ with kbts_GlyphIteratorNext.++ Note that kbts_ShapeDirect does not care about the paragraph direction.+ Glyphs are always returned in left-to-right order. In other words, RTL runs+ are flipped so that visual order is consistent.+++ :kbts_ShapeDirectFixedMemory+ :ShapeDirectFixedMemory+ kbts_shape_error kbts_ShapeDirectFixedMemory(kbts_shape_config *Config, kbts_glyph_storage *Storage,+ kbts_direction RunDirection,+ void *Memory, int Size,+ kbts_glyph_iterator *Output)+ Same as kbts_ShapeDirect, but only uses the [Size] bytes at [Memory] for allocations.++ The rest of the direct API is more or less about preparing the data you need to call+ kbts_ShapeDirect.++ DIRECT:FONT HANDLING+ :kbts_FontCount+ :FontCount+ int kbts_FontCount(void *Data, int Size)+ Parses the beginning of the file and returns the number of fonts contained+ within the file data.++ While most font files contain single fonts, font collections contain+ several. This function will return 0 if [Data] is invalid, 1 if it represents+ a single font, and possibly more if it represents a collection.++ For all functions that require a font index, passing 0 is always safe no+ matter the kind of file.++ :kbts_FontFromFile+ :FontFromFile+ kbts_font kbts_FontFromFile(const char *FileName, int FontIndex,+ kbts_allocator_function *Allocator, void *AllocatorData,+ void **FileData, int *FileSize)+ (This function is not available if KB_TEXT_SHAPE_NO_CRT is defined.)+ Opens the file at [FileName], parses it and returns the [FontIndex]th font.+ You can call kbts_FontIsValid to check if the [return value] is usable.++ If [FileData] is non-zero, it is filled with a pointer to the file's contents.+ This pointer is allocated using [Allocator]. If [FileData] is 0, it is freed+ before the function returns.+ If [FileSize] is non-zero, it is filled with the size of the file's contents.++ If [FontIndex] is out of range, the [return value] is invalid.++ :kbts_FontFromMemory+ :FontFromMemory+ kbts_font kbts_FontFromMemory(void *FileData, int FileSize, int FontIndex,+ kbts_allocator_function *Allocator, void *AllocatorData)+ Parses the [FontIndex]th font in [FileData].+ You can call kbts_FontIsValid to check if the [return value] is usable.++ :kbts_FontIsValid+ :FontIsValid+ int kbts_FontIsValid(kbts_font *Font)+ Returns whether a font is usable.++ :kbts_LoadFont+ :LoadFont+ kbts_load_font_error kbts_LoadFont(kbts_font *Font, kbts_load_font_state *State,+ void *FontData, int FontDataSize, int FontIndex,+ int *ScratchSize, int *OutputSize)+ Parses the [FontIndex]th font in [FontData] and puts the result into [Font] and [State].++ [State] needs to be zeroed before calling this function.++ If the data represents a TrueType/OpenType font, we need to extract the data+ we need and create some additional data structures. In this case, the [return+ value] is KBTS_LOAD_FONT_ERROR_NEED_TO_CREATE_BLOB, and [ScratchSize] and+ [OutputSize] are filled with the amount of memory we need to create our+ blob. You can then initialize this blob with kbts_PlaceBlob.++ If the data represents a kbts blob, then nothing needs to be done, and [Font] is+ immediately usable.++ Any value of [FontIndex] less than kbts_FontCount(FontData, FontDataSize) is+ acceptable.++ If we could not find any useful font data, the [return value] is+ KBTS_LOAD_FONT_ERROR_INVALID_FONT.++ :kbts_PlaceBlob+ :PlaceBlob+ kbts_load_font_error kbts_PlaceBlob(kbts_font *Font, kbts_load_font_state *State,+ void *ScratchMemory, void *OutputMemory)+ Creates a kbts blob from font data, and places it in [OutputMemory].+ [Font] is the resulting font.+ [State] is the state you passed into kbts_LoadFont.+ [ScratchMemory] needs to be as big as the [ScratchSize] returned by kbts_LoadFont.+ You can free this buffer once this function returns.+ [OutputMemory] needs to be as big as the [OutputSize] returned by kbts_LoadFont.+ This buffer will be used by [Font] until it is freed by kbts_FreeFont.++ :kbts_FreeFont+ :FreeFont+ void kbts_FreeFont(kbts_font *Font)+ If [Font] used allocators to allocate its data (for instance, if [Font] was+ returned by kbts_FontFromFile), frees all of [Font]'s buffers.+ Otherwise, does nothing.++ :kbts_GetFontInfo+ :GetFontInfo+ void kbts_GetFontInfo(kbts_font *Font, kbts_font_info *Info)+ Writes a bunch of useful metadata about [Font] into [Info].+ You can use this function to extract styling, name and licensing information+ from a font.++ We use a simplified representation for font weight and width that is fine for+ classic font selection, e.g. "I need a bold font". OpenType fonts may feature+ finer-grained metrics, and we currently do not expose/support those.++ :kbts_font_style_flags+ :font_style_flags+ [Info]->StyleFlags can be:+ KBTS_FONT_STYLE_FLAG_NONE (no useful style flags have been found)+ KBTS_FONT_STYLE_FLAG_REGULAR+ KBTS_FONT_STYLE_FLAG_BOLD+ KBTS_FONT_STYLE_FLAG_ITALIC+ A given font can be bold and italic at the same time, but probably not regular+ and bold and probably not regular and italic.++ If [Font] is not a valid font, then [Info] will be zeroed.++ DIRECT:SHAPE CONFIG+ :kbts_SizeOfShapeConfig+ :SizeOfShapeConfig+ int kbts_SizeOfShapeConfig(kbts_font *Font, kbts_script Script, kbts_language Language)+ Returns how large the buffer you pass into kbts_PlaceShapeConfig needs to be.++ :kbts_PlaceShapeConfig+ :PlaceShapeConfig+ kbts_shape_config *kbts_PlaceShapeConfig(kbts_font *Font, kbts_script Script, kbts_language Language,+ void *Memory)+ Writes a shape config into [Memory] and returns a pointer to it.+ [Memory] needs to be at least kbts_SizeOfShapeConfig([Font], [Script], [Language]) bytes.++ :kbts_CreateShapeConfig+ :CreateShapeConfig+ kbts_shape_config *kbts_CreateShapeConfig(kbts_font *Font, kbts_script Script, kbts_language Language,+ kbts_allocator_function *Allocator, void *AllocatorData)+ Allocates and initializes a shape config.++ :kbts_DestroyShapeConfig+ :DestroyShapeConfig+ void kbts_DestroyShapeConfig(kbts_shape_config *Config)+ If [Config] was allocated in kbts_CreateShapeConfig, frees all of [Config]'s data.+ Otherwise, nothing is done.++ DIRECT:GLYPH STORAGE+ kbts_glyph_storage is a public struct:++ :kbts_glyph_storage+ :glyph_storage+ typedef struct kbts_glyph_storage+ {+ kbts_arena Arena;++ kbts_glyph GlyphSentinel;+ kbts_glyph FreeGlyphSentinel;+ } kbts_glyph_storage;++ A zeroed kbts_glyph_storage will auto-initialize itself when you try to use it.++ Arena requires an allocator. By default, it will be initialized to KBTS_MALLOC+ and KBTS_FREE.+ You can specify your own allocator by writing to Arena.Allocator and+ Arena.AllocatorData before trying to use a kbts_glyph_storage.+ Alternatively, you can use kbts_InitializeGlyphStorage() to accomplish the+ same thing.++ :kbts_InitializeGlyphStorage+ :InitializeGlyphStorage+ int kbts_InitializeGlyphStorage(kbts_glyph_storage *Storage, kbts_allocator_function *Allocator, void *AllocatorData)+ Initializes [Storage] to use [Allocator] and [AllocatorData].++ This is equivalent to setting [Storage]->Arena.Allocator and+ [Storage]->Arena.AllocatorData, and setting all other members to 0.++ The [return value] is non-zero if [Storage] is non-null.++ :kbts_InitializeGlyphStorageFixedMemory+ :InitializeGlyphStorageFixedMemory+ int kbts_InitializeGlyphStorageFixedMemory(kbts_glyph_storage *Storage, void *Memory, int MemorySize)+ Initializes [Storage] to use a fixed-size buffer of size [MemorySize] located at [Memory].+ If [Storage] needs more memory than [MemorySize], allocations will fail.++ The [return value] is non-zero if [Storage] is non-null and [MemorySize] is+ large enough to initialize [Storage]'s arena. (Currently, this is 5 pointers'+ worth of bytes.)++ :kbts_PushGlyph+ :PushGlyph+ kbts_glyph *kbts_PushGlyph(kbts_glyph_storage *Storage,+ kbts_font *Font, int Codepoint, kbts_glyph_config *Config, int UserId)+ Adds a glyph to [Storage]'s active glyph set and returns a pointer to it.++ [Font] is used to initialize the glyph's glyph ID. It is assumed that [Font] is+ the same as the kbts_shape_config's Font field passed into kbts_ShapeDirect.++ [Config] is the glyph's configuration and needs to stay live until kbts_ShapeDirect+ completes. See DIRECT:GLYPH CONFIG for more details.++ [UserId] is a user-provided unique identifier that you can get back once shaping+ is done.++ The [return value] might be zero if [Storage]'s allocator fails.++ :kbts_ClearActiveGlyphs+ :ClearActiveGlyphs+ void kbts_ClearActiveGlyphs(kbts_glyph_storage *Storage)+ Clears [Storage]'s active glyph set.+ This does not free any memory; rather, it puts the active glyphs in a free list.++ :kbts_FreeAllGlyphs+ :FreeAllGlyphs+ void kbts_FreeAllGlyphs(kbts_glyph_storage *Storage)+ Frees all memory allocated by [Storage].++ :kbts_CodepointToGlyph+ :CodepointToGlyph+ kbts_glyph kbts_CodepointToGlyph(kbts_font *Font, int Codepoint, kbts_glyph_config *Config, int UserId)+ You can create glyphs without a glyph storage at all with this function.++ :kbts_CodepointToGlyphId+ :CodepointToGlyphId+ int kbts_CodepointToGlyphId(kbts_font *Font, int Codepoint)+ Gets the glyph ID corresponding to [Codepoint] from [Font].+ A glyph ID of 0 means that the codepoint is not present in the font.+ Note that this is not thorough enough to be a good font coverage test!+ See OTHER:FONT COVERAGE TEST for this.++ :kbts_ActiveGlyphIterator+ :ActiveGlyphIterator+ kbts_glyph_iterator kbts_ActiveGlyphIterator(kbts_glyph_storage *Storage)+ Returns an iterator to traverse [Storage]'s active glyph set.++ See OTHER:GLYPH ITERATION for more details on glyph iterators.++ DIRECT:GLYPH CONFIG+ The shaper figures out most of the work it needs to do based on the writing system+ it is shaping.++ However, some fonts support optional, toggleable features, like "make this text+ smallcaps". For things like this, you will want to create a kbts_glyph_config.+ You can then pass it to glyph creation functions or write it to the Config field+ of a kbts_glyph.++ A kbts_glyph_config can hold any number of feature overrides. A feature override+ is a feature tag and a value. Most of the time, you only care whether the value+ is 0 or 1, but a few features actually care about the exact value. (You can think+ of a feature that is like "when I am enabled, change this letter to one of these+ alternatives". In that case, the value you provide in the feature override is used+ as an index into the array of alternatives.)++ :kbts_SizeOfGlyphConfig+ :SizeOfGlyphConfig+ int kbts_SizeOfGlyphConfig(kbts_feature_override *Overrides, int OverrideCount)+ Returns the buffer size needed to hold a kbts_glyph_config that describes [Overrides].+ This size can vary a lot depending on the kind of feature overrides you specify.+ Built-in OpenType features with values of 0 or 1 are "free"; they are packed in a+ fixed-size representation which does not change the config's memory footprint.+ On the other hand, if you need non-binary values, or non-standard features, then+ we need to store a description of the override itself, which requires memory.++ :kbts_PlaceGlyphConfig+ :PlaceGlyphConfig+ kbts_glyph_config *kbts_PlaceGlyphConfig(kbts_feature_override *Overrides, int OverrideCount, void *Memory)+ Writes a kbts_glyph_config that describes [Overrides] into [Memory], and returns a+ pointer to it.+ The kbts_glyph_config uses its own representation for overrides, so you can modify+ [Overrides] once this function returns.++ :kbts_CreateGlyphConfig+ :CreateGlyphConfig+ kbts_glyph_config *kbts_CreateGlyphConfig(kbts_feature_override *Overrides, int OverrideCount, kbts_allocator_function *Allocator, void *AllocatorData)+ Allocates a kbts_glyph_config that describes [Overrides] and returns a pointer to+ it.+ The kbts_glyph_config uses its own representation for overrides, so you can modify+ [Overrides] once this function returns.++ :kbts_DestroyGlyphConfig+ :DestroyGlyphConfig+ void kbts_DestroyGlyphConfig(kbts_glyph_config *Config)+ If [Config] was allocated in kbts_CreateGlyphConfig, frees all of its data.+ Otherwise, does nothing.++ DIRECT:SEGMENTATION+ kbts_break_state is the central struct used for segmentation. It contains all of the state+ needed to perform fixed-memory segmentation of text.++ :kbts_BreakBegin+ :BreakBegin+ void kbts_BreakBegin(kbts_break_state *State,+ kbts_direction ParagraphDirection,+ kbts_japanese_line_break_style JapaneseLineBreakStyle,+ kbts_break_config_flags ConfigFlags)+ Initializes [State] for segmentation.++ [ParagraphDirection] is the top-level flow direction of your document or layout.+ If [ParagraphDirection] is KBTS_DIRECTION_DONT_KNOW, then [State]'s+ ParagraphDirection will be initialized to the first direction we find+ while segmenting.++ :kbts_japanese_line_break_style+ :japanese_line_break_style+ [JapaneseLineBreakStyle] can be one of the following:++ KBTS_JAPANESE_LINE_BREAK_STYLE_STRICT+ KBTS_JAPANESE_LINE_BREAK_STYLE_NORMAL+ KBTS_JAPANESE_LINE_BREAK_STYLE_LOOSE++ Japanese text contains "kinsoku" characters, around which breaking a line is+ forbidden. Exactly which characters are "kinsoku" or not depends on the context:++ - Strict style has the largest amount of kinsoku characters, which leads to+ longer lines.+ The Unicode standard does not define what strict style is used for.+ Supposedly, it is used for anything that does not fall into the other+ two categories of text.++ - Loose style has the smallest amount of kinsoku characters, which leads+ to smaller lines.+ According to the Unicode standard, loose style is used for newspapers.+ I assume it is also used for any other narrow column format.++ - Normal style is somewhere in the middle.+ According to the Unicode standard, normal style is used for books and+ documents.++ Note that, while the Unicode standard mentions all three of these styles, it+ does not mention any differences between the normal and loose styles. As such,+ normal and loose styles currently behave the same.++ :kbts_kbts_break_config_flags+ :kbts_break_config_flags+ [ConfigFlags] can be a combination of the following:++ KBTS_BREAK_CONFIG_FLAG_END_OF_TEXT_GENERATES_HARD_LINE_BREAK+ The Unicode standard specifies that the end of a text should generate a+ hard line break. However, this is an awkward rule to uphold in practical+ contexts, because it makes the case where the text ends in a newline+ ambiguous. So, by default, we disable it.++ Without this flag (default behavior):+ <start of text>\n<end of text> generates a hard line break at position 1+ <start of text>A<end of text> generates no hard line break++ With this flag (Unicode behavior):+ <start of text>\n<end of text> generates a hard line break at position 1+ <start of text>A<end of text> generates a hard line break at position 1++ :kbts_BreakAddCodepoint+ :BreakAddCodepoint+ void kbts_BreakAddCodepoint(kbts_break_state *State, int Codepoint, int PositionIncrement, int EndOfText)+ Feeds [Codepoint] to [State].++ [PositionIncrement] is used to update an internal cursor and fill out+ kbts_break's Position field. If you only care about codepoint indices, pass+ 1. Maybe you want to pass in the number of bytes it took to decode the+ codepoint, though, to be able to directly index UTF-8 text.++ If [EndOfText] is non-zero, kbts_BreakEnd is called after adding [Codepoint].++ Every time you call kbts_BreakAddCodepoint, you need to empty the break+ buffer by calling kbts_Break repeatedly.++ :kbts_BreakEnd+ :BreakEnd+ void kbts_BreakEnd(kbts_break_state *State)+ Flushes all pending breaks and finishes segmentation.++ You then obtain breaks by repeatedly calling kbts_Break, just as you would+ after kbts_BreakAddCodepoint.++ :kbts_Break+ :Break+ int kbts_Break(kbts_break_state *State, kbts_break *Break)+ If any breaks have been found, writes one to [Break] and returns a non-zero+ value. If not, returns 0.++ kbts_break looks like this:++ typedef struct kbts_break+ {+ int Position;+ kbts_break_flags Flags;+ kbts_direction Direction; // Only valid if (Flags & KBTS_BREAK_FLAG_DIRECTION).+ kbts_script Script; // Only valid if (Flags & KBTS_BREAK_FLAG_SCRIPT).+ } kbts_break;++ Position is the position of the break, informed by the PositionIncrement+ you passed to kbts_BreakAddCodepoint.++ Flags can be any combination of:+ KBTS_BREAK_FLAG_DIRECTION+ Indicates a change of direction.++ KBTS_BREAK_FLAG_SCRIPT+ Indicates a change of script.++ KBTS_BREAK_FLAG_GRAPHEME+ Indicates the start of a grapheme.+ Unicode describes a grapheme as a visual unit. In practice, you care about+ graphemes for font coverage testing and caret positioning.++ The way you do grapheme-aware font coverage testing is you split your text+ into graphemes, then, for each grapheme, check if it is supported by your+ font. Grapheme boundaries are nice because they group codepoints that may+ want to combine together, but it separates codepoints that probably won't+ recombine, so they work as an synchronization point for font coverage.++ Caret positioning typically works in graphemes, too. When the user presses+ the right arrow, you would go to the next grapheme boundary instead of+ naively going to the next codepoint.++ KBTS_BREAK_FLAG_WORD+ Indicates the start of a word.++ KBTS_BREAK_FLAG_LINE_SOFT+ A soft line break tells you where you are able to break lines.+ In Unicode land, you cannot break a line without one of these!++ KBTS_BREAK_FLAG_LINE_HARD+ A hard line break should always be respected.++ KBTS_BREAK_FLAG_MANUAL+ This is used internally by the kbts_shape_context for manual segmentation.+ (See kbts_ShapeBeginManualRuns for more details.)++ !CAREFUL! For a given break type, breaks are guaranteed to be returned in order.+ However, there is no such ordering guarantee between different types+ of breaks. Each type of break is processed separately, and the+ corresponding Unicode algorithms all require some kind of buffering+ scheme to work in fixed memory, so, while any given buffer is consistent+ with itself, we cannot order multiple buffers together.++ :kbts_BreakEntireString+ :BreakEntireString+ void kbts_BreakEntireString(kbts_direction ParagraphDirection,+ kbts_japanese_line_break_style JapaneseLineBreakStyle,+ kbts_break_config_flags ConfigFlags,+ void *Input, int InputSizeInBytes, kbts_text_format InputFormat,+ kbts_break *Breaks, int BreakCapacity, int *BreakCount,+ kbts_break_flags *BreakFlags, int BreakFlagCapacity, int *BreakFlagCount)+ Goes through the entire buffer at [Input] and finds all breaks.+ [Input] is of type [InputFormat], which can be one of:+ KBTS_TEXT_FORMAT_UTF32+ KBTS_TEXT_FORMAT_UTF8++ Breaks will be written to [Breaks], up to [BreakCapacity]. Regardless of+ whether [BreakCapacity] is large enough or not, the amount of breaks found+ will be written to [BreakCount]. Unlike kbts_Break, here, [Breaks] are+ guaranteed to be ordered.++ [BreakFlags] is a parallel array to the input sequence. If a break is found+ at position X, then BreakFlags[X] will be filled with the appropriate flags,+ up to [BreakFlagCapacity]. Regardless of whether [BreakFlagCapacity] is large+ enough or not, the required capacity is written to [BreakFlagCount].++ :kbts_BreakEntireStringUtf32+ :BreakEntireStringUtf32+ void kbts_BreakEntireStringUtf32(kbts_direction ParagraphDirection,+ kbts_japanese_line_break_style JapaneseLineBreakStyle,+ kbts_break_config_flags ConfigFlags,+ int *Utf32, int Utf32Count,+ kbts_break *Breaks, int BreakCapacity, int *BreakCount,+ kbts_break_flags *BreakFlags, int BreakFlagCapacity, int *BreakFlagCount)+ Convenience wrapper for kbts_BreakEntireString for UTF-32 text.++ :kbts_BreakEntireStringUtf8+ :BreakEntireStringUtf8+ void kbts_BreakEntireStringUtf8(kbts_direction ParagraphDirection,+ kbts_japanese_line_break_style JapaneseLineBreakStyle,+ kbts_break_config_flags ConfigFlags,+ const char *Utf8, int Utf8Length,+ kbts_break *Breaks, int BreakCapacity, int *BreakCount,+ kbts_break_flags *BreakFlags, int BreakFlagCapacity, int *BreakFlagCount)+ Convenience wrapper for kbts_BreakEntireString for UTF-8 text.++ This wrapper passes the amount of bytes used to decode each codepoint into+ kbts_BreakAddCodepoint's PositionIncrement argument. This means that break+ positions written to [Breaks] point into the UTF-8 stream.++ :kbts_GuessTextProperties+ :GuessTextProperties+ void kbts_GuessTextProperties(void *Text, int TextSizeInBytes, kbts_text_format Format,+ kbts_direction *Direction, kbts_script *Script)+ Goes through the input sequence at [Text], finds the first direction and+ script, and writes them to [Direction] and [Script] respectively.++ This is a quick-and-dirty way of finding out simple facts about your text.+ However, the results only really make sense when you know [Input] is+ mono-script and mono-direction.++ :kbts_GuessTextPropertiesUtf32+ :GuessTextPropertiesUtf32+ void kbts_GuessTextPropertiesUtf32(const int *Utf32, int Utf32Count,+ kbts_direction *Direction, kbts_script *Script)+ Convenience wrapper for kbts_GuessTextProperties for UTF-32 text.++ :kbts_GuessTextPropertiesUtf8+ :GuessTextPropertiesUtf8+ void kbts_GuessTextPropertiesUtf8(const char *Utf8, int Utf8Length,+ kbts_direction *Direction, kbts_script *Script)+ Convenience wrapper for kbts_GuessTextProperties for UTF-8 text.++ OTHER APIS+ OTHER:GLYPH ITERATION+ :kbts_GlyphIteratorNext+ :GlyphIteratorNext+ int kbts_GlyphIteratorNext(kbts_glyph_iterator *It, kbts_glyph **Glyph)+ Writes the next glyph to iterate over in [Glyph].++ Once shaping is done, the interesting members of a glyph are:+ - Id: the glyph index/id in the font.+ - UserId: the user ID you passed in when creating the glyph.+ This is typically some kind of codepoint index you can use to trace back+ the glyph to your source text.+ - AdvanceX/Y and OffsetX/Y: positioning data.+ Here is how you might use them:++ kbts_glyph *Glyph;+ int CursorX = 0, CursorY = 0;+ while(kbts_GlyphIteratorNext(&It, &Glyph))+ {+ int GlyphX = CursorX + Glyph->OffsetX;+ int GlyphY = CursorY + Glyph->OffsetY;++ CursorX += Glyph->AdvanceX;+ CursorY += Glyph->AdvanceY;+ }++ You cannot assume that [Glyph] will stay valid if you free its glyph storage,+ begin another shaping operation using the same glyph storage, or do any kind+ of manipulation involving the glyph storage that holds this glyph. Likewise,+ you should probably not assume that [Glyph] will stay valid after the next+ call to kbts_GlyphIteratorNext.++ The [return value] is 1 if we found a glyph to return, and 0 if we did not.+ Once kbts_GlyphIteratorNext has returned 0, you can keep calling it and+ it will keep returning 0.++ :kbts_GlyphIteratorIsValid+ :GlyphIteratorIsValid+ int kbts_GlyphIteratorIsValid(kbts_glyph_iterator *It)+ Returns whether there are still glyphs left to iterate over.++ If this returns a non-zero value, then the next call to+ kbts_GlyphIteratorNext will also return a non-zero value and write a valid+ glyph.++ OTHER:FONT COVERAGE TEST+ To implement font fallback, you need to be able to know if a given span of text+ is supported by a given font. However, this process is not as simple as it sounds.+ Some Unicode codepoints have "canonical decompositions" and "canonical+ recompositions" that are meant to describe different ways to represent the same+ text, but with different codepoints. At the beginning of the shaping process,+ shapers try all combinations until one is found that is fully supported by the+ font. A font coverage test does this within a fixed memory footprint.++ :kbts_FontCoverageTestBegin+ :FontCoverageTestBegin+ void kbts_FontCoverageTestBegin(kbts_font_coverage_test *Test, kbts_font *Font)+ Initializes [Test] to test coverage with [Font].++ :kbts_FontCoverageTestCodepoint+ :FontCoverageTestCodepoint+ void kbts_FontCoverageTestCodepoint(kbts_font_coverage_test *Test, int Codepoint)+ Feeds [Codepoint] into [Test] and updates coverage information.++ :kbts_FontCoverageTestEnd+ :FontCoverageTestEnd+ int kbts_FontCoverageTestEnd(kbts_font_coverage_test *Test)+ Flushes the pending combinations not yet tested by [Test] and ends the coverage+ test.+ The [return value] is non-zero if the text is fully supported by the font,+ whereas it is 0 if any glyph was not supported.+ You can also check Test->Error to see if any glyph was unsupported.++ OTHER:OTHER OTHER:MISC+ :kbts_DecodeUtf8+ :DecodeUtf8+ kbts_decode kbts_DecodeUtf8(const char *Utf8, kbts_un Length)+ Tries to decode a single codepoint from [Utf8].+ kbts_decode looks like this:++ typedef struct kbts_decode+ {+ int Codepoint;++ int SourceCharactersConsumed;+ int Valid;+ } kbts_decode;++ Codepoint is the decoded codepoint.+ SourceCharactersConsumed is the amount of bytes that were read from [Utf8].+ If decoding was successful, Valid is non-zero. Otherwise, it is zero.+ Valid is zero if we run out of characters, or if the characters in [Utf8]+ are invalid.++ :kbts_EncodeUtf8+ :EncodeUtf8+ kbts_encode_utf8 kbts_EncodeUtf8(int Codepoint)+ Tries to encode a single codepoint into a UTF-8 sequence of bytes.+ kbts_encode looks like this:++ typedef struct kbts_encode_utf8+ {+ char Encoded[4];+ int EncodedLength;+ int Valid;+ } kbts_encode_utf8;++ Encoded is the encoded sequence.+ EncodedLength is the number of bytes needed to encode [Codepoint].+ Valid is whether or not [Codepoint] is a valid codepoint to encode.+ (All codepoints up to 0x10FFFF inclusive can be encoded.)+ When Valid is 0, EncodedLength is also 0.++ :kbts_ScriptDirection+ :ScriptDirection+ kbts_direction kbts_ScriptDirection(kbts_script Script)+ Returns the default direction for a given script.++ :kbts_ScriptIsComplex+ :ScriptIsComplex+ int kbts_ScriptIsComplex(kbts_script Script)+ Returns whether a script is complex, i.e. if it requires complex shaper+ support.++ :kbts_ScriptTagToScript+ :ScriptTagToScript+ kbts_script kbts_ScriptTagToScript(kbts_script_tag Tag)+ Returns a given script from a four-character tag.+ A kbts_script_tag can be obtained either through the KBTS_SCRIPT_TAG_*+ constants, or through the KBTS_FOURCC() macro, which creates a tag from+ four characters.++ LANGUAGE SUPPORT+ Shaping is NOT supported for the following scripts:+ Zawgyi: some fonts exist, but no standardized OpenType feature set seems to exist as of writing.+ Syriac: Syriac Abbreviation Mark (0x070F) is not supported.+ Egyptian Hieroglyphs, I think, although example text is hard to come by.+ Word breaking is NOT supported for languages that require word dictionaries, like CJK.++ FONT SUPPORT+ Indic fonts using the Indic1 shaping model are not supported.+ e.g., 'bng2' will work, but 'beng' will not.+ The Indic v2 shaping model was released with OpenType 1.5 in May 2008.+ Traditional Arabic Windows 3.1 fonts are not supported.+ https://github.com/harfbuzz/harfbuzz/issues/681+ Thai/Lao PUA fonts are not supported.+ These are old fonts that use OS-specific codepages (PUA stands for [Unicode] "Private Use Area") and+ pre-OpenType shaping.+ https://linux.thai.net/~thep/th-otf/shaping.html+ More generally, we try to be compatible with most well-formed fonts, but we try less hard than Harfbuzz+ to be compatible with every font under the sun.++ OTHER LIMITATIONS+ Explicit direction control characters are not supported. This includes:+ 0x202A Left-to-right embedding+ 0x202B Right-to-left embedding+ 0x202D Left-to-right override+ 0x202E Right-to-left override+ 0x202C Pop directional formatting+ 0x2066 Left-to-right isolate+ 0x2067 Right-to-left isolate+ 0x2068 First strong isolate+ 0x2069 Pop directional isolate+ See https://unicode.org/reports/tr9 for more information.++ VERSION HISTORY+ 2.06 - Faster GSUB and GPOS feature culling.+ 2.05 - Fix custom allocator initialization for kbts_shape_context.PermanentArena.+ 2.04 - Fix Indic syllable logic for small/single-character syllables.+ Fix wrong indirection in pointer code in Indic syllable logic.+ 2.03 - Fix loading blobs directly, fix a parsing edge case in GPOS format 2 subtables.+ 2.02 - Improve globbing of cursive attachments.+ 2.01 - Add kbts_InitializeGlyphStorage and kbts_ScriptDirection.+ Rename some private functions for better namespacing.+ Delete some deprecated functions.+ Bounds check in kbts_ScriptIsComplex.+ Fix a couple pointer iteration bugs.+ Fix some pedantic MSVC warnings.+ Extend mirroring logic from brackets to any codepoint that has a Unicode mirror.+ 2.0 - Completely new API and implementation.+ 1.03 - New functions: kbts_FeatureTagToId(), kbts_FeatureOverrideFromTag(), kbts_EmptyGlyphConfig(), kbts_GlyphConfigOverrideFeature(), kbts_GlyphConfigOverrideFeatureFromTag(), kbts_ScriptTagToScript()+ Unregistered features can now be overriden using their tags.+ This is slower than overriding registered features, i.e. those that have a kbts_feature_id.+ Compiler warning cleanup+ 1.02b - Feature control for GPOS features+ Bounds checking in ReadFontHeader+ 1.02a - Positioning fix for format 2 GPOS pair adjustments+ 1.02 - Added per-glyph manual feature control through kbts_FeatureOverride(), kbts_GlyphConfig()+ Added enum definitions for features cv01-cv99 and ss01-ss20+ 1.01 - Header cleanup and glyph output documentation+ 1.0 - Initial release++ TODO+ Word dictionaries for word breaking: CJK, etc.+ 'stch' feature.++ LICENSE+ zlib License++ (C) Copyright 2024-2025 Jimmy Lefevre++ This software is provided 'as-is', without any express or implied+ warranty. In no event will the authors be held liable for any damages+ arising from the use of this software.++ Permission is granted to anyone to use this software for any purpose,+ including commercial applications, and to alter it and redistribute it+ freely, subject to the following restrictions:++ 1. The origin of this software must not be misrepresented; you must not+ claim that you wrote the original software. If you use this software+ in a product, an acknowledgment in the product documentation would be+ appreciated but is not required.+ 2. Altered source versions must be plainly marked as such, and must not be+ misrepresented as being the original software.+ 3. This notice may not be removed or altered from any source distribution.+*/++#ifndef KB_TEXT_SHAPE_INCLUDED+# define KB_TEXT_SHAPE_INCLUDED++# ifndef kbts_s64+# if defined(_MSC_VER) || defined(__BORLANDC__)+# define kbts_s64 __int64+# else+# define kbts_s64 long long+# endif+# endif+# ifndef kbts_u64+# if defined(_MSC_VER) || defined(__BORLANDC__)+# define kbts_u64 unsigned __int64+# else+# define kbts_u64 unsigned long long+# endif+# endif+# ifndef kbts_u32+# define kbts_u32 unsigned+# endif+# ifndef kbts_u16+# define kbts_u16 unsigned short+# endif+# ifndef kbts_s32+# define kbts_s32 int+# endif+# ifndef kbts_s16+# define kbts_s16 short+# endif+# ifndef kbts_u8+# define kbts_u8 unsigned char+# endif+# ifndef kbts_s8+# define kbts_s8 signed char+# endif++# ifndef KB_TEXT_SHAPE_POINTER_SIZE+# if defined(i386) || defined(__i386__) || defined(_M_IX86) || defined(_M_ARM) || defined(__arm__) || defined(__x86) || (defined(__APPLE__) && defined(__ppc)) || \+ (defined(__TOS_AIX__) && !defined(__64BIT))+# define KB_TEXT_SHAPE_POINTER_SIZE 4+# else+# define KB_TEXT_SHAPE_POINTER_SIZE 8+# endif+# endif++# if KB_TEXT_SHAPE_POINTER_SIZE == 4+# define kbts_un kbts_u32+# define kbts_sn kbts_s32+# else+# define kbts_un kbts_u64+# define kbts_sn kbts_s64+# endif++# ifdef __has_attribute+# if __has_attribute(fallthrough)+# define KBTS_FALLTHROUGH __attribute__((fallthrough))+# endif+# endif+# ifndef KBTS_FALLTHROUGH+# define KBTS_FALLTHROUGH+# endif++# ifndef KBTS_EXPORT+# ifdef KB_TEXT_SHAPE_STATIC+# define KBTS_EXPORT static+# else+# ifdef __cplusplus+# define KBTS_EXPORT extern "C"+# else+# define KBTS_EXPORT extern+# endif+# endif+# endif++# ifdef _MSC_VER+# define KBTS_INLINE static __forceinline+# define KBTS_NOINLINE static __declspec(noinline)+# define KBTS_ALIGNOF __alignof+# else+# ifdef __has_attribute+# if __has_attribute(always_inline)+# define KBTS_INLINE static inline __attribute__((always_inline))+# endif+# if __has_attribute(noinline)+# define KBTS_NOINLINE static __attribute__((noinline))+# endif+# endif+# define KBTS_ALIGNOF __alignof__+# endif+# ifndef KBTS_INLINE+# define KBTS_INLINE static inline+# endif++# define KBTS_FOURCC(A, B, C, D) ((A) | ((B) << 8) | ((C) << 16) | ((D) << 24))++typedef kbts_u32 kbts_language;+enum kbts_language_enum+{+ KBTS_LANGUAGE_DONT_KNOW = 0,++ KBTS_LANGUAGE_A_HMAO = KBTS_FOURCC('H', 'M', 'D', ' '),+ KBTS_LANGUAGE_AARI = KBTS_FOURCC('A', 'R', 'I', ' '),+ KBTS_LANGUAGE_ABAZA = KBTS_FOURCC('A', 'B', 'A', ' '),+ KBTS_LANGUAGE_ABKHAZIAN = KBTS_FOURCC('A', 'B', 'K', ' '),+ KBTS_LANGUAGE_ACHI = KBTS_FOURCC('A', 'C', 'R', ' '),+ KBTS_LANGUAGE_ACHOLI = KBTS_FOURCC('A', 'C', 'H', ' '),+ KBTS_LANGUAGE_ADYGHE = KBTS_FOURCC('A', 'D', 'Y', ' '),+ KBTS_LANGUAGE_AFAR = KBTS_FOURCC('A', 'F', 'R', ' '),+ KBTS_LANGUAGE_AFRIKAANS = KBTS_FOURCC('A', 'F', 'K', ' '),+ KBTS_LANGUAGE_AGAW = KBTS_FOURCC('A', 'G', 'W', ' '),+ KBTS_LANGUAGE_AITON = KBTS_FOURCC('A', 'I', 'O', ' '),+ KBTS_LANGUAGE_AKAN = KBTS_FOURCC('A', 'K', 'A', ' '),+ KBTS_LANGUAGE_ALBANIAN = KBTS_FOURCC('S', 'Q', 'I', ' '),+ KBTS_LANGUAGE_ALSATIAN = KBTS_FOURCC('A', 'L', 'S', ' '),+ KBTS_LANGUAGE_ALTAI = KBTS_FOURCC('A', 'L', 'T', ' '),+ KBTS_LANGUAGE_ALUO = KBTS_FOURCC('Y', 'N', 'A', ' '),+ KBTS_LANGUAGE_AMERICAN_PHONETIC = KBTS_FOURCC('A', 'P', 'P', 'H'),+ KBTS_LANGUAGE_AMHARIC = KBTS_FOURCC('A', 'M', 'H', ' '),+ KBTS_LANGUAGE_ANGLO_SAXON = KBTS_FOURCC('A', 'N', 'G', ' '),+ KBTS_LANGUAGE_ARABIC = KBTS_FOURCC('A', 'R', 'A', ' '),+ KBTS_LANGUAGE_ARAGONESE = KBTS_FOURCC('A', 'R', 'G', ' '),+ KBTS_LANGUAGE_ARAKANESE = KBTS_FOURCC('A', 'R', 'K', ' '),+ KBTS_LANGUAGE_ARAKWAL = KBTS_FOURCC('R', 'K', 'W', ' '),+ KBTS_LANGUAGE_ARMENIAN = KBTS_FOURCC('H', 'Y', 'E', ' '),+ KBTS_LANGUAGE_ARMENIAN_EAST = KBTS_FOURCC('H', 'Y', 'E', '0'),+ KBTS_LANGUAGE_AROMANIAN = KBTS_FOURCC('R', 'U', 'P', ' '),+ KBTS_LANGUAGE_ARPITAN = KBTS_FOURCC('F', 'R', 'P', ' '),+ KBTS_LANGUAGE_ASSAMESE = KBTS_FOURCC('A', 'S', 'M', ' '),+ KBTS_LANGUAGE_ASTURIAN = KBTS_FOURCC('A', 'S', 'T', ' '),+ KBTS_LANGUAGE_ATHAPASKAN = KBTS_FOURCC('A', 'T', 'H', ' '),+ KBTS_LANGUAGE_ATSINA = KBTS_FOURCC('A', 'T', 'S', ' '),+ KBTS_LANGUAGE_AVAR = KBTS_FOURCC('A', 'V', 'R', ' '),+ KBTS_LANGUAGE_AVATIME = KBTS_FOURCC('A', 'V', 'N', ' '),+ KBTS_LANGUAGE_AWADHI = KBTS_FOURCC('A', 'W', 'A', ' '),+ KBTS_LANGUAGE_AYMARA = KBTS_FOURCC('A', 'Y', 'M', ' '),+ KBTS_LANGUAGE_AZERBAIDJANI = KBTS_FOURCC('A', 'Z', 'E', ' '),+ KBTS_LANGUAGE_BADAGA = KBTS_FOURCC('B', 'A', 'D', ' '),+ KBTS_LANGUAGE_BAGHELKHANDI = KBTS_FOURCC('B', 'A', 'G', ' '),+ KBTS_LANGUAGE_BAGRI = KBTS_FOURCC('B', 'G', 'Q', ' '),+ KBTS_LANGUAGE_BALANTE = KBTS_FOURCC('B', 'L', 'N', ' '),+ KBTS_LANGUAGE_BALINESE = KBTS_FOURCC('B', 'A', 'N', ' '),+ KBTS_LANGUAGE_BALKAR = KBTS_FOURCC('B', 'A', 'L', ' '),+ KBTS_LANGUAGE_BALTI = KBTS_FOURCC('B', 'L', 'T', ' '),+ KBTS_LANGUAGE_BALUCHI = KBTS_FOURCC('B', 'L', 'I', ' '),+ KBTS_LANGUAGE_BAMBARA = KBTS_FOURCC('B', 'M', 'B', ' '),+ KBTS_LANGUAGE_BAMILEKE = KBTS_FOURCC('B', 'M', 'L', ' '),+ KBTS_LANGUAGE_BANDA = KBTS_FOURCC('B', 'A', 'D', '0'),+ KBTS_LANGUAGE_BANDJALANG = KBTS_FOURCC('B', 'D', 'Y', ' '),+ KBTS_LANGUAGE_BANGLA = KBTS_FOURCC('B', 'E', 'N', ' '),+ KBTS_LANGUAGE_BASHKIR = KBTS_FOURCC('B', 'S', 'H', ' '),+ KBTS_LANGUAGE_BASQUE = KBTS_FOURCC('E', 'U', 'Q', ' '),+ KBTS_LANGUAGE_BATAK = KBTS_FOURCC('B', 'T', 'K', ' '),+ KBTS_LANGUAGE_BATAK_ALAS_KLUET = KBTS_FOURCC('B', 'T', 'Z', ' '),+ KBTS_LANGUAGE_BATAK_ANGKOLA = KBTS_FOURCC('A', 'K', 'B', ' '),+ KBTS_LANGUAGE_BATAK_DAIRI = KBTS_FOURCC('B', 'T', 'D', ' '),+ KBTS_LANGUAGE_BATAK_KARO = KBTS_FOURCC('B', 'T', 'X', ' '),+ KBTS_LANGUAGE_BATAK_MANDAILING = KBTS_FOURCC('B', 'T', 'M', ' '),+ KBTS_LANGUAGE_BATAK_SIMALUNGUN = KBTS_FOURCC('B', 'T', 'S', ' '),+ KBTS_LANGUAGE_BATAK_TOBA = KBTS_FOURCC('B', 'B', 'C', ' '),+ KBTS_LANGUAGE_BAULE = KBTS_FOURCC('B', 'A', 'U', ' '),+ KBTS_LANGUAGE_BAVARIAN = KBTS_FOURCC('B', 'A', 'R', ' '),+ KBTS_LANGUAGE_BELARUSIAN = KBTS_FOURCC('B', 'E', 'L', ' '),+ KBTS_LANGUAGE_BEMBA = KBTS_FOURCC('B', 'E', 'M', ' '),+ KBTS_LANGUAGE_BENCH = KBTS_FOURCC('B', 'C', 'H', ' '),+ KBTS_LANGUAGE_BERBER = KBTS_FOURCC('B', 'B', 'R', ' '),+ KBTS_LANGUAGE_BETI = KBTS_FOURCC('B', 'T', 'I', ' '),+ KBTS_LANGUAGE_BETTE_KURUMA = KBTS_FOURCC('X', 'U', 'B', ' '),+ KBTS_LANGUAGE_BHILI = KBTS_FOURCC('B', 'H', 'I', ' '),+ KBTS_LANGUAGE_BHOJPURI = KBTS_FOURCC('B', 'H', 'O', ' '),+ KBTS_LANGUAGE_BHUTANESE = KBTS_FOURCC('D', 'Z', 'N', ' '),+ KBTS_LANGUAGE_BIBLE_CREE = KBTS_FOURCC('B', 'C', 'R', ' '),+ KBTS_LANGUAGE_BIKOL = KBTS_FOURCC('B', 'I', 'K', ' '),+ KBTS_LANGUAGE_BILEN = KBTS_FOURCC('B', 'I', 'L', ' '),+ KBTS_LANGUAGE_BISHNUPRIYA_MANIPURI = KBTS_FOURCC('B', 'P', 'Y', ' '),+ KBTS_LANGUAGE_BISLAMA = KBTS_FOURCC('B', 'I', 'S', ' '),+ KBTS_LANGUAGE_BLACKFOOT = KBTS_FOURCC('B', 'K', 'F', ' '),+ KBTS_LANGUAGE_BODO = KBTS_FOURCC('B', 'R', 'X', ' '),+ KBTS_LANGUAGE_BOSNIAN = KBTS_FOURCC('B', 'O', 'S', ' '),+ KBTS_LANGUAGE_BOUYEI = KBTS_FOURCC('P', 'C', 'C', ' '),+ KBTS_LANGUAGE_BRAHUI = KBTS_FOURCC('B', 'R', 'H', ' '),+ KBTS_LANGUAGE_BRAJ_BHASHA = KBTS_FOURCC('B', 'R', 'I', ' '),+ KBTS_LANGUAGE_BRETON = KBTS_FOURCC('B', 'R', 'E', ' '),+ KBTS_LANGUAGE_BUGIS = KBTS_FOURCC('B', 'U', 'G', ' '),+ KBTS_LANGUAGE_BULGARIAN = KBTS_FOURCC('B', 'G', 'R', ' '),+ KBTS_LANGUAGE_BUMTHANGKHA = KBTS_FOURCC('K', 'J', 'Z', ' '),+ KBTS_LANGUAGE_BURMESE = KBTS_FOURCC('B', 'R', 'M', ' '),+ KBTS_LANGUAGE_BURUSHASKI = KBTS_FOURCC('B', 'S', 'K', ' '),+ KBTS_LANGUAGE_CAJUN_FRENCH = KBTS_FOURCC('F', 'R', 'C', ' '),+ KBTS_LANGUAGE_CARRIER = KBTS_FOURCC('C', 'R', 'R', ' '),+ KBTS_LANGUAGE_CATALAN = KBTS_FOURCC('C', 'A', 'T', ' '),+ KBTS_LANGUAGE_CAYUGA = KBTS_FOURCC('C', 'A', 'Y', ' '),+ KBTS_LANGUAGE_CEBUANO = KBTS_FOURCC('C', 'E', 'B', ' '),+ KBTS_LANGUAGE_CENTRAL_YUPIK = KBTS_FOURCC('E', 'S', 'U', ' '),+ KBTS_LANGUAGE_CHAHA_GURAGE = KBTS_FOURCC('C', 'H', 'G', ' '),+ KBTS_LANGUAGE_CHAMORRO = KBTS_FOURCC('C', 'H', 'A', ' '),+ KBTS_LANGUAGE_CHATTISGARHI = KBTS_FOURCC('C', 'H', 'H', ' '),+ KBTS_LANGUAGE_CHECHEN = KBTS_FOURCC('C', 'H', 'E', ' '),+ KBTS_LANGUAGE_CHEROKEE = KBTS_FOURCC('C', 'H', 'R', ' '),+ KBTS_LANGUAGE_CHEYENNE = KBTS_FOURCC('C', 'H', 'Y', ' '),+ KBTS_LANGUAGE_CHICHEWA = KBTS_FOURCC('C', 'H', 'I', ' '),+ KBTS_LANGUAGE_CHIGA = KBTS_FOURCC('C', 'G', 'G', ' '),+ KBTS_LANGUAGE_CHIMILA = KBTS_FOURCC('C', 'B', 'G', ' '),+ KBTS_LANGUAGE_CHIN = KBTS_FOURCC('Q', 'I', 'N', ' '),+ KBTS_LANGUAGE_CHINANTEC = KBTS_FOURCC('C', 'C', 'H', 'N'),+ KBTS_LANGUAGE_CHINESE_PHONETIC = KBTS_FOURCC('Z', 'H', 'P', ' '),+ KBTS_LANGUAGE_CHINESE_SIMPLIFIED = KBTS_FOURCC('Z', 'H', 'S', ' '),+ KBTS_LANGUAGE_CHINESE_TRADITIONAL = KBTS_FOURCC('Z', 'H', 'T', ' '),+ KBTS_LANGUAGE_CHINESE_TRADITIONAL_HONG_KONG = KBTS_FOURCC('Z', 'H', 'H', ' '),+ KBTS_LANGUAGE_CHINESE_TRADITIONAL_MACAO = KBTS_FOURCC('Z', 'H', 'T', 'M'),+ KBTS_LANGUAGE_CHIPEWYAN = KBTS_FOURCC('C', 'H', 'P', ' '),+ KBTS_LANGUAGE_CHITTAGONIAN = KBTS_FOURCC('C', 'T', 'G', ' '),+ KBTS_LANGUAGE_CHOCTAW = KBTS_FOURCC('C', 'H', 'O', ' '),+ KBTS_LANGUAGE_CHUKCHI = KBTS_FOURCC('C', 'H', 'K', ' '),+ KBTS_LANGUAGE_CHURCH_SLAVONIC = KBTS_FOURCC('C', 'S', 'L', ' '),+ KBTS_LANGUAGE_CHUUKESE = KBTS_FOURCC('C', 'H', 'K', '0'),+ KBTS_LANGUAGE_CHUVASH = KBTS_FOURCC('C', 'H', 'U', ' '),+ KBTS_LANGUAGE_COMORIAN = KBTS_FOURCC('C', 'M', 'R', ' '),+ KBTS_LANGUAGE_COMOX = KBTS_FOURCC('C', 'O', 'O', ' '),+ KBTS_LANGUAGE_COPTIC = KBTS_FOURCC('C', 'O', 'P', ' '),+ KBTS_LANGUAGE_CORNISH = KBTS_FOURCC('C', 'O', 'R', ' '),+ KBTS_LANGUAGE_CORSICAN = KBTS_FOURCC('C', 'O', 'S', ' '),+ KBTS_LANGUAGE_CREE = KBTS_FOURCC('C', 'R', 'E', ' '),+ KBTS_LANGUAGE_CREOLES = KBTS_FOURCC('C', 'P', 'P', ' '),+ KBTS_LANGUAGE_CRIMEAN_TATAR = KBTS_FOURCC('C', 'R', 'T', ' '),+ KBTS_LANGUAGE_CRIOULO = KBTS_FOURCC('K', 'E', 'A', ' '),+ KBTS_LANGUAGE_CROATIAN = KBTS_FOURCC('H', 'R', 'V', ' '),+ KBTS_LANGUAGE_CYPRIOT_ARABIC = KBTS_FOURCC('A', 'C', 'Y', ' '),+ KBTS_LANGUAGE_CZECH = KBTS_FOURCC('C', 'S', 'Y', ' '),+ KBTS_LANGUAGE_DAGBANI = KBTS_FOURCC('D', 'A', 'G', ' '),+ KBTS_LANGUAGE_DAN = KBTS_FOURCC('D', 'N', 'J', ' '),+ KBTS_LANGUAGE_DANGME = KBTS_FOURCC('D', 'N', 'G', ' '),+ KBTS_LANGUAGE_DANISH = KBTS_FOURCC('D', 'A', 'N', ' '),+ KBTS_LANGUAGE_DARGWA = KBTS_FOURCC('D', 'A', 'R', ' '),+ KBTS_LANGUAGE_DARI = KBTS_FOURCC('D', 'R', 'I', ' '),+ KBTS_LANGUAGE_DAYI = KBTS_FOURCC('D', 'A', 'X', ' '),+ KBTS_LANGUAGE_DEFAULT = KBTS_FOURCC('d', 'f', 'l', 't'), // Can be DFLT too...+ KBTS_LANGUAGE_DEHONG_DAI = KBTS_FOURCC('T', 'D', 'D', ' '),+ KBTS_LANGUAGE_DHANGU = KBTS_FOURCC('D', 'H', 'G', ' '),+ KBTS_LANGUAGE_DHIVEHI = KBTS_FOURCC('D', 'I', 'V', ' '),+ KBTS_LANGUAGE_DHUWAL = KBTS_FOURCC('D', 'U', 'J', ' '),+ KBTS_LANGUAGE_DIMLI = KBTS_FOURCC('D', 'I', 'Q', ' '),+ KBTS_LANGUAGE_DINKA = KBTS_FOURCC('D', 'N', 'K', ' '),+ KBTS_LANGUAGE_DIVEHI = KBTS_FOURCC('D', 'I', 'V', ' '),+ KBTS_LANGUAGE_DJAMBARRPUYNGU = KBTS_FOURCC('D', 'J', 'R', '0'),+ KBTS_LANGUAGE_DOGRI = KBTS_FOURCC('D', 'G', 'O', ' '),+ KBTS_LANGUAGE_DOGRI_MACROLANGUAGE = KBTS_FOURCC('D', 'G', 'R', ' '),+ KBTS_LANGUAGE_DUNGAN = KBTS_FOURCC('D', 'U', 'N', ' '),+ KBTS_LANGUAGE_DUTCH = KBTS_FOURCC('N', 'L', 'D', ' '),+ KBTS_LANGUAGE_DZONGKHA = KBTS_FOURCC('D', 'Z', 'N', ' '),+ KBTS_LANGUAGE_EASTERN_ABENAKI = KBTS_FOURCC('A', 'A', 'Q', ' '),+ KBTS_LANGUAGE_EASTERN_CHAM = KBTS_FOURCC('C', 'J', 'M', ' '),+ KBTS_LANGUAGE_EASTERN_CREE = KBTS_FOURCC('E', 'C', 'R', ' '),+ KBTS_LANGUAGE_EASTERN_MANINKAKAN = KBTS_FOURCC('E', 'M', 'K', ' '),+ KBTS_LANGUAGE_EASTERN_PWO_KAREN = KBTS_FOURCC('K', 'J', 'P', ' '),+ KBTS_LANGUAGE_EBIRA = KBTS_FOURCC('E', 'B', 'I', ' '),+ KBTS_LANGUAGE_EDO = KBTS_FOURCC('E', 'D', 'O', ' '),+ KBTS_LANGUAGE_EFIK = KBTS_FOURCC('E', 'F', 'I', ' '),+ KBTS_LANGUAGE_EMBERA_BAUDO = KBTS_FOURCC('B', 'D', 'C', ' '),+ KBTS_LANGUAGE_EMBERA_CATIO = KBTS_FOURCC('C', 'T', 'O', ' '),+ KBTS_LANGUAGE_EMBERA_CHAMI = KBTS_FOURCC('C', 'M', 'I', ' '),+ KBTS_LANGUAGE_EMBERA_TADO = KBTS_FOURCC('T', 'D', 'C', ' '),+ KBTS_LANGUAGE_ENGLISH = KBTS_FOURCC('E', 'N', 'G', ' '),+ KBTS_LANGUAGE_EPENA = KBTS_FOURCC('S', 'J', 'A', ' '),+ KBTS_LANGUAGE_ERZYA = KBTS_FOURCC('E', 'R', 'Z', ' '),+ KBTS_LANGUAGE_KB_TEXT_SHAPEANTO = KBTS_FOURCC('N', 'T', 'O', ' '),+ KBTS_LANGUAGE_ESTONIAN = KBTS_FOURCC('E', 'T', 'I', ' '),+ KBTS_LANGUAGE_EVEN = KBTS_FOURCC('E', 'V', 'N', ' '),+ KBTS_LANGUAGE_EVENKI = KBTS_FOURCC('E', 'V', 'K', ' '),+ KBTS_LANGUAGE_EWE = KBTS_FOURCC('E', 'W', 'E', ' '),+ KBTS_LANGUAGE_FALAM_CHIN = KBTS_FOURCC('H', 'A', 'L', ' '),+ KBTS_LANGUAGE_FANG = KBTS_FOURCC('F', 'A', 'N', '0'),+ KBTS_LANGUAGE_FANTI = KBTS_FOURCC('F', 'A', 'T', ' '),+ KBTS_LANGUAGE_FAROESE = KBTS_FOURCC('F', 'O', 'S', ' '),+ KBTS_LANGUAGE_FEFE = KBTS_FOURCC('F', 'M', 'P', ' '),+ KBTS_LANGUAGE_FIJIAN = KBTS_FOURCC('F', 'J', 'I', ' '),+ KBTS_LANGUAGE_FILIPINO = KBTS_FOURCC('P', 'I', 'L', ' '),+ KBTS_LANGUAGE_FINNISH = KBTS_FOURCC('F', 'I', 'N', ' '),+ KBTS_LANGUAGE_FLEMISH = KBTS_FOURCC('F', 'L', 'E', ' '),+ KBTS_LANGUAGE_FON = KBTS_FOURCC('F', 'O', 'N', ' '),+ KBTS_LANGUAGE_FOREST_ENETS = KBTS_FOURCC('F', 'N', 'E', ' '),+ KBTS_LANGUAGE_FRENCH = KBTS_FOURCC('F', 'R', 'A', ' '),+ KBTS_LANGUAGE_FRENCH_ANTILLEAN = KBTS_FOURCC('F', 'A', 'N', ' '),+ KBTS_LANGUAGE_FRISIAN = KBTS_FOURCC('F', 'R', 'I', ' '),+ KBTS_LANGUAGE_FRIULIAN = KBTS_FOURCC('F', 'R', 'L', ' '),+ KBTS_LANGUAGE_FULAH = KBTS_FOURCC('F', 'U', 'L', ' '),+ KBTS_LANGUAGE_FUTA = KBTS_FOURCC('F', 'T', 'A', ' '),+ KBTS_LANGUAGE_GA = KBTS_FOURCC('G', 'A', 'D', ' '),+ KBTS_LANGUAGE_GAGAUZ = KBTS_FOURCC('G', 'A', 'G', ' '),+ KBTS_LANGUAGE_GALICIAN = KBTS_FOURCC('G', 'A', 'L', ' '),+ KBTS_LANGUAGE_GANDA = KBTS_FOURCC('L', 'U', 'G', ' '),+ KBTS_LANGUAGE_GARHWALI = KBTS_FOURCC('G', 'A', 'W', ' '),+ KBTS_LANGUAGE_GARO = KBTS_FOURCC('G', 'R', 'O', ' '),+ KBTS_LANGUAGE_GARSHUNI = KBTS_FOURCC('G', 'A', 'R', ' '),+ KBTS_LANGUAGE_GEBA_KAREN = KBTS_FOURCC('K', 'V', 'Q', ' '),+ KBTS_LANGUAGE_GEEZ = KBTS_FOURCC('G', 'E', 'Z', ' '),+ KBTS_LANGUAGE_GEORGIAN = KBTS_FOURCC('K', 'A', 'T', ' '),+ KBTS_LANGUAGE_GEPO = KBTS_FOURCC('Y', 'G', 'P', ' '),+ KBTS_LANGUAGE_GERMAN = KBTS_FOURCC('D', 'E', 'U', ' '),+ KBTS_LANGUAGE_GIKUYU = KBTS_FOURCC('K', 'I', 'K', ' '),+ KBTS_LANGUAGE_GILAKI = KBTS_FOURCC('G', 'L', 'K', ' '),+ KBTS_LANGUAGE_GILBERTESE = KBTS_FOURCC('G', 'I', 'L', '0'),+ KBTS_LANGUAGE_GILYAK = KBTS_FOURCC('G', 'I', 'L', ' '),+ KBTS_LANGUAGE_GITHABUL = KBTS_FOURCC('G', 'I', 'H', ' '),+ KBTS_LANGUAGE_GOGO = KBTS_FOURCC('G', 'O', 'G', ' '),+ KBTS_LANGUAGE_GONDI = KBTS_FOURCC('G', 'O', 'N', ' '),+ KBTS_LANGUAGE_GREEK = KBTS_FOURCC('E', 'L', 'L', ' '),+ KBTS_LANGUAGE_GREENLANDIC = KBTS_FOURCC('G', 'R', 'N', ' '),+ KBTS_LANGUAGE_GUARANI = KBTS_FOURCC('G', 'U', 'A', ' '),+ KBTS_LANGUAGE_GUINEA = KBTS_FOURCC('G', 'K', 'P', ' '),+ KBTS_LANGUAGE_GUJARATI = KBTS_FOURCC('G', 'U', 'J', ' '),+ KBTS_LANGUAGE_GUMATJ = KBTS_FOURCC('G', 'N', 'N', ' '),+ KBTS_LANGUAGE_GUMUZ = KBTS_FOURCC('G', 'M', 'Z', ' '),+ KBTS_LANGUAGE_GUPAPUYNGU = KBTS_FOURCC('G', 'U', 'F', ' '),+ KBTS_LANGUAGE_GUSII = KBTS_FOURCC('G', 'U', 'Z', ' '),+ KBTS_LANGUAGE_HAIDA = KBTS_FOURCC('H', 'A', 'I', '0'),+ KBTS_LANGUAGE_HAITIAN_CREOLE = KBTS_FOURCC('H', 'A', 'I', ' '),+ KBTS_LANGUAGE_HALKOMELEM = KBTS_FOURCC('H', 'U', 'R', ' '),+ KBTS_LANGUAGE_HAMMER_BANNA = KBTS_FOURCC('H', 'B', 'N', ' '),+ KBTS_LANGUAGE_HARARI = KBTS_FOURCC('H', 'R', 'I', ' '),+ KBTS_LANGUAGE_HARAUTI = KBTS_FOURCC('H', 'A', 'R', ' '),+ KBTS_LANGUAGE_HARYANVI = KBTS_FOURCC('B', 'G', 'C', ' '),+ KBTS_LANGUAGE_HAUSA = KBTS_FOURCC('H', 'A', 'U', ' '),+ KBTS_LANGUAGE_HAVASUPAI_WALAPAI_YAVAPAI = KBTS_FOURCC('Y', 'U', 'F', ' '),+ KBTS_LANGUAGE_HAWAIIAN = KBTS_FOURCC('H', 'A', 'W', ' '),+ KBTS_LANGUAGE_HAYA = KBTS_FOURCC('H', 'A', 'Y', ' '),+ KBTS_LANGUAGE_HAZARAGI = KBTS_FOURCC('H', 'A', 'Z', ' '),+ KBTS_LANGUAGE_HEBREW = KBTS_FOURCC('I', 'W', 'R', ' '),+ KBTS_LANGUAGE_HEILTSUK = KBTS_FOURCC('H', 'E', 'I', ' '),+ KBTS_LANGUAGE_HERERO = KBTS_FOURCC('H', 'E', 'R', ' '),+ KBTS_LANGUAGE_HIGH_MARI = KBTS_FOURCC('H', 'M', 'A', ' '),+ KBTS_LANGUAGE_HILIGAYNON = KBTS_FOURCC('H', 'I', 'L', ' '),+ KBTS_LANGUAGE_HINDI = KBTS_FOURCC('H', 'I', 'N', ' '),+ KBTS_LANGUAGE_HINDKO = KBTS_FOURCC('H', 'N', 'D', ' '),+ KBTS_LANGUAGE_HIRI_MOTU = KBTS_FOURCC('H', 'M', 'O', ' '),+ KBTS_LANGUAGE_HMONG = KBTS_FOURCC('H', 'M', 'N', ' '),+ KBTS_LANGUAGE_HMONG_DAW = KBTS_FOURCC('M', 'W', 'W', ' '),+ KBTS_LANGUAGE_HMONG_SHUAT = KBTS_FOURCC('H', 'M', 'Z', ' '),+ KBTS_LANGUAGE_HO = KBTS_FOURCC('H', 'O', ' ', ' '),+ KBTS_LANGUAGE_HUNGARIAN = KBTS_FOURCC('H', 'U', 'N', ' '),+ KBTS_LANGUAGE_IBAN = KBTS_FOURCC('I', 'B', 'A', ' '),+ KBTS_LANGUAGE_IBIBIO = KBTS_FOURCC('I', 'B', 'B', ' '),+ KBTS_LANGUAGE_ICELANDIC = KBTS_FOURCC('I', 'S', 'L', ' '),+ KBTS_LANGUAGE_IDO = KBTS_FOURCC('I', 'D', 'O', ' '),+ KBTS_LANGUAGE_IGBO = KBTS_FOURCC('I', 'B', 'O', ' '),+ KBTS_LANGUAGE_IJO = KBTS_FOURCC('I', 'J', 'O', ' '),+ KBTS_LANGUAGE_ILOKANO = KBTS_FOURCC('I', 'L', 'O', ' '),+ KBTS_LANGUAGE_INARI_SAMI = KBTS_FOURCC('I', 'S', 'M', ' '),+ KBTS_LANGUAGE_INDONESIAN = KBTS_FOURCC('I', 'N', 'D', ' '),+ KBTS_LANGUAGE_INGUSH = KBTS_FOURCC('I', 'N', 'G', ' '),+ KBTS_LANGUAGE_INTERLINGUA = KBTS_FOURCC('I', 'N', 'A', ' '),+ KBTS_LANGUAGE_INTERLINGUE = KBTS_FOURCC('I', 'L', 'E', ' '),+ KBTS_LANGUAGE_INUKTITUT = KBTS_FOURCC('I', 'N', 'U', ' '),+ KBTS_LANGUAGE_INUPIAT = KBTS_FOURCC('I', 'P', 'K', ' '),+ KBTS_LANGUAGE_IPA_PHONETIC = KBTS_FOURCC('I', 'P', 'P', ' '),+ KBTS_LANGUAGE_IRISH = KBTS_FOURCC('I', 'R', 'I', ' '),+ KBTS_LANGUAGE_IRISH_TRADITIONAL = KBTS_FOURCC('I', 'R', 'T', ' '),+ KBTS_LANGUAGE_IRULA = KBTS_FOURCC('I', 'R', 'U', ' '),+ KBTS_LANGUAGE_ITALIAN = KBTS_FOURCC('I', 'T', 'A', ' '),+ KBTS_LANGUAGE_JAMAICAN_CREOLE = KBTS_FOURCC('J', 'A', 'M', ' '),+ KBTS_LANGUAGE_JAPANESE = KBTS_FOURCC('J', 'A', 'N', ' '),+ KBTS_LANGUAGE_JAVANESE = KBTS_FOURCC('J', 'A', 'V', ' '),+ KBTS_LANGUAGE_JENNU_KURUMA = KBTS_FOURCC('X', 'U', 'J', ' '),+ KBTS_LANGUAGE_JUDEO_TAT = KBTS_FOURCC('J', 'D', 'T', ' '),+ KBTS_LANGUAGE_JULA = KBTS_FOURCC('J', 'U', 'L', ' '),+ KBTS_LANGUAGE_KABARDIAN = KBTS_FOURCC('K', 'A', 'B', ' '),+ KBTS_LANGUAGE_KABYLE = KBTS_FOURCC('K', 'A', 'B', '0'),+ KBTS_LANGUAGE_KACHCHI = KBTS_FOURCC('K', 'A', 'C', ' '),+ KBTS_LANGUAGE_KADIWEU = KBTS_FOURCC('K', 'B', 'C', ' '),+ KBTS_LANGUAGE_KALENJIN = KBTS_FOURCC('K', 'A', 'L', ' '),+ KBTS_LANGUAGE_KALMYK = KBTS_FOURCC('K', 'L', 'M', ' '),+ KBTS_LANGUAGE_KAMBA = KBTS_FOURCC('K', 'M', 'B', ' '),+ KBTS_LANGUAGE_KANAUJI = KBTS_FOURCC('B', 'J', 'J', ' '),+ KBTS_LANGUAGE_KANNADA = KBTS_FOURCC('K', 'A', 'N', ' '),+ KBTS_LANGUAGE_KANURI = KBTS_FOURCC('K', 'N', 'R', ' '),+ KBTS_LANGUAGE_KAQCHIKEL = KBTS_FOURCC('C', 'A', 'K', ' '),+ KBTS_LANGUAGE_KARACHAY = KBTS_FOURCC('K', 'A', 'R', ' '),+ KBTS_LANGUAGE_KARAIM = KBTS_FOURCC('K', 'R', 'M', ' '),+ KBTS_LANGUAGE_KARAKALPAK = KBTS_FOURCC('K', 'R', 'K', ' '),+ KBTS_LANGUAGE_KARELIAN = KBTS_FOURCC('K', 'R', 'L', ' '),+ KBTS_LANGUAGE_KAREN = KBTS_FOURCC('K', 'R', 'N', ' '),+ KBTS_LANGUAGE_KASHMIRI = KBTS_FOURCC('K', 'S', 'H', ' '),+ KBTS_LANGUAGE_KASHUBIAN = KBTS_FOURCC('C', 'S', 'B', ' '),+ KBTS_LANGUAGE_KATE = KBTS_FOURCC('K', 'M', 'G', ' '),+ KBTS_LANGUAGE_KAZAKH = KBTS_FOURCC('K', 'A', 'Z', ' '),+ KBTS_LANGUAGE_KEBENA = KBTS_FOURCC('K', 'E', 'B', ' '),+ KBTS_LANGUAGE_KEKCHI = KBTS_FOURCC('K', 'E', 'K', ' '),+ KBTS_LANGUAGE_KHAKASS = KBTS_FOURCC('K', 'H', 'A', ' '),+ KBTS_LANGUAGE_KHAMTI_SHAN = KBTS_FOURCC('K', 'H', 'T', ' '),+ KBTS_LANGUAGE_KHAMYANG = KBTS_FOURCC('K', 'S', 'U', ' '),+ KBTS_LANGUAGE_KHANTY_KAZIM = KBTS_FOURCC('K', 'H', 'K', ' '),+ KBTS_LANGUAGE_KHANTY_SHURISHKAR = KBTS_FOURCC('K', 'H', 'S', ' '),+ KBTS_LANGUAGE_KHANTY_VAKHI = KBTS_FOURCC('K', 'H', 'V', ' '),+ KBTS_LANGUAGE_KHASI = KBTS_FOURCC('K', 'S', 'I', ' '),+ KBTS_LANGUAGE_KHENGKHA = KBTS_FOURCC('X', 'K', 'F', ' '),+ KBTS_LANGUAGE_KHINALUG = KBTS_FOURCC('K', 'J', 'J', ' '),+ KBTS_LANGUAGE_KHMER = KBTS_FOURCC('K', 'H', 'M', ' '),+ KBTS_LANGUAGE_KHORASANI_TURKIC = KBTS_FOURCC('K', 'M', 'Z', ' '),+ KBTS_LANGUAGE_KHOWAR = KBTS_FOURCC('K', 'H', 'W', ' '),+ KBTS_LANGUAGE_KHUTSURI_GEORGIAN = KBTS_FOURCC('K', 'G', 'E', ' '),+ KBTS_LANGUAGE_KICHE = KBTS_FOURCC('Q', 'U', 'C', ' '),+ KBTS_LANGUAGE_KIKONGO = KBTS_FOURCC('K', 'O', 'N', ' '),+ KBTS_LANGUAGE_KILDIN_SAMI = KBTS_FOURCC('K', 'S', 'M', ' '),+ KBTS_LANGUAGE_KINYARWANDA = KBTS_FOURCC('R', 'U', 'A', ' '),+ KBTS_LANGUAGE_KIRMANJKI = KBTS_FOURCC('K', 'I', 'U', ' '),+ KBTS_LANGUAGE_KISII = KBTS_FOURCC('K', 'I', 'S', ' '),+ KBTS_LANGUAGE_KITUBA = KBTS_FOURCC('M', 'K', 'W', ' '),+ KBTS_LANGUAGE_KODAGU = KBTS_FOURCC('K', 'O', 'D', ' '),+ KBTS_LANGUAGE_KOKNI = KBTS_FOURCC('K', 'K', 'N', ' '),+ KBTS_LANGUAGE_KOMI = KBTS_FOURCC('K', 'O', 'M', ' '),+ KBTS_LANGUAGE_KOMI_PERMYAK = KBTS_FOURCC('K', 'O', 'P', ' '),+ KBTS_LANGUAGE_KOMI_ZYRIAN = KBTS_FOURCC('K', 'O', 'Z', ' '),+ KBTS_LANGUAGE_KOMO = KBTS_FOURCC('K', 'M', 'O', ' '),+ KBTS_LANGUAGE_KOMSO = KBTS_FOURCC('K', 'M', 'S', ' '),+ KBTS_LANGUAGE_KONGO = KBTS_FOURCC('K', 'O', 'N', '0'),+ KBTS_LANGUAGE_KONKANI = KBTS_FOURCC('K', 'O', 'K', ' '),+ KBTS_LANGUAGE_KOORETE = KBTS_FOURCC('K', 'R', 'T', ' '),+ KBTS_LANGUAGE_KOREAN = KBTS_FOURCC('K', 'O', 'R', ' '),+ KBTS_LANGUAGE_KOREAO_OLD_HANGUL = KBTS_FOURCC('K', 'O', 'H', ' '),+ KBTS_LANGUAGE_KORYAK = KBTS_FOURCC('K', 'Y', 'K', ' '),+ KBTS_LANGUAGE_KOSRAEAN = KBTS_FOURCC('K', 'O', 'S', ' '),+ KBTS_LANGUAGE_KPELLE = KBTS_FOURCC('K', 'P', 'L', ' '),+ KBTS_LANGUAGE_KPELLE_LIBERIA = KBTS_FOURCC('X', 'P', 'E', ' '),+ KBTS_LANGUAGE_KRIO = KBTS_FOURCC('K', 'R', 'I', ' '),+ KBTS_LANGUAGE_KRYMCHAK = KBTS_FOURCC('J', 'C', 'T', ' '),+ KBTS_LANGUAGE_KUANYAMA = KBTS_FOURCC('K', 'U', 'A', ' '),+ KBTS_LANGUAGE_KUBE = KBTS_FOURCC('K', 'G', 'F', ' '),+ KBTS_LANGUAGE_KUI = KBTS_FOURCC('K', 'U', 'I', ' '),+ KBTS_LANGUAGE_KULVI = KBTS_FOURCC('K', 'U', 'K', ' '),+ KBTS_LANGUAGE_KUMAONI = KBTS_FOURCC('K', 'M', 'N', ' '),+ KBTS_LANGUAGE_KUMYK = KBTS_FOURCC('K', 'U', 'M', ' '),+ KBTS_LANGUAGE_KURDISH = KBTS_FOURCC('K', 'U', 'R', ' '),+ KBTS_LANGUAGE_KURUKH = KBTS_FOURCC('K', 'U', 'U', ' '),+ KBTS_LANGUAGE_KUY = KBTS_FOURCC('K', 'U', 'Y', ' '),+ KBTS_LANGUAGE_KWAKWALA = KBTS_FOURCC('K', 'W', 'K', ' '),+ KBTS_LANGUAGE_KYRGYZ = KBTS_FOURCC('K', 'I', 'R', ' '),+ KBTS_LANGUAGE_L_CREE = KBTS_FOURCC('L', 'C', 'R', ' '),+ KBTS_LANGUAGE_LADAKHI = KBTS_FOURCC('L', 'D', 'K', ' '),+ KBTS_LANGUAGE_LADIN = KBTS_FOURCC('L', 'A', 'D', ' '),+ KBTS_LANGUAGE_LADINO = KBTS_FOURCC('J', 'U', 'D', ' '),+ KBTS_LANGUAGE_LAHULI = KBTS_FOURCC('L', 'A', 'H', ' '),+ KBTS_LANGUAGE_LAK = KBTS_FOURCC('L', 'A', 'K', ' '),+ KBTS_LANGUAGE_LAKI = KBTS_FOURCC('L', 'K', 'I', ' '),+ KBTS_LANGUAGE_LAMBANI = KBTS_FOURCC('L', 'A', 'M', ' '),+ KBTS_LANGUAGE_LAMPUNG = KBTS_FOURCC('L', 'J', 'P', ' '),+ KBTS_LANGUAGE_LAO = KBTS_FOURCC('L', 'A', 'O', ' '),+ KBTS_LANGUAGE_LATIN = KBTS_FOURCC('L', 'A', 'T', ' '),+ KBTS_LANGUAGE_LATVIAN = KBTS_FOURCC('L', 'V', 'I', ' '),+ KBTS_LANGUAGE_LAZ = KBTS_FOURCC('L', 'A', 'Z', ' '),+ KBTS_LANGUAGE_LELEMI = KBTS_FOURCC('L', 'E', 'F', ' '),+ KBTS_LANGUAGE_LEZGI = KBTS_FOURCC('L', 'E', 'Z', ' '),+ KBTS_LANGUAGE_LIGURIAN = KBTS_FOURCC('L', 'I', 'J', ' '),+ KBTS_LANGUAGE_LIMBU = KBTS_FOURCC('L', 'M', 'B', ' '),+ KBTS_LANGUAGE_LIMBURGISH = KBTS_FOURCC('L', 'I', 'M', ' '),+ KBTS_LANGUAGE_LINGALA = KBTS_FOURCC('L', 'I', 'N', ' '),+ KBTS_LANGUAGE_LIPO = KBTS_FOURCC('L', 'P', 'O', ' '),+ KBTS_LANGUAGE_LISU = KBTS_FOURCC('L', 'I', 'S', ' '),+ KBTS_LANGUAGE_LITHUANIAN = KBTS_FOURCC('L', 'T', 'H', ' '),+ KBTS_LANGUAGE_LIV = KBTS_FOURCC('L', 'I', 'V', ' '),+ KBTS_LANGUAGE_LOJBAN = KBTS_FOURCC('J', 'B', 'O', ' '),+ KBTS_LANGUAGE_LOMA = KBTS_FOURCC('L', 'O', 'M', ' '),+ KBTS_LANGUAGE_LOMBARD = KBTS_FOURCC('L', 'M', 'O', ' '),+ KBTS_LANGUAGE_LOMWE = KBTS_FOURCC('L', 'M', 'W', ' '),+ KBTS_LANGUAGE_LOW_MARI = KBTS_FOURCC('L', 'M', 'A', ' '),+ KBTS_LANGUAGE_LOW_SAXON = KBTS_FOURCC('N', 'D', 'S', ' '),+ KBTS_LANGUAGE_LOWER_SORBIAN = KBTS_FOURCC('L', 'S', 'B', ' '),+ KBTS_LANGUAGE_LU = KBTS_FOURCC('X', 'B', 'D', ' '),+ KBTS_LANGUAGE_LUBA_KATANGA = KBTS_FOURCC('L', 'U', 'B', ' '),+ KBTS_LANGUAGE_LUBA_LULUA = KBTS_FOURCC('L', 'U', 'A', ' '),+ KBTS_LANGUAGE_LULE_SAMI = KBTS_FOURCC('L', 'S', 'M', ' '),+ KBTS_LANGUAGE_LUO = KBTS_FOURCC('L', 'U', 'O', ' '),+ KBTS_LANGUAGE_LURI = KBTS_FOURCC('L', 'R', 'C', ' '),+ KBTS_LANGUAGE_LUSHOOTSEED = KBTS_FOURCC('L', 'U', 'T', ' '),+ KBTS_LANGUAGE_LUXEMBOURGISH = KBTS_FOURCC('L', 'T', 'Z', ' '),+ KBTS_LANGUAGE_LUYIA = KBTS_FOURCC('L', 'U', 'H', ' '),+ KBTS_LANGUAGE_MACEDONIAN = KBTS_FOURCC('M', 'K', 'D', ' '),+ KBTS_LANGUAGE_MADURA = KBTS_FOURCC('M', 'A', 'D', ' '),+ KBTS_LANGUAGE_MAGAHI = KBTS_FOURCC('M', 'A', 'G', ' '),+ KBTS_LANGUAGE_MAITHILI = KBTS_FOURCC('M', 'T', 'H', ' '),+ KBTS_LANGUAGE_MAJANG = KBTS_FOURCC('M', 'A', 'J', ' '),+ KBTS_LANGUAGE_MAKASAR = KBTS_FOURCC('M', 'K', 'R', ' '),+ KBTS_LANGUAGE_MAKHUWA = KBTS_FOURCC('M', 'A', 'K', ' '),+ KBTS_LANGUAGE_MAKONDE = KBTS_FOURCC('K', 'D', 'E', ' '),+ KBTS_LANGUAGE_MALAGASY = KBTS_FOURCC('M', 'L', 'G', ' '),+ KBTS_LANGUAGE_MALAY = KBTS_FOURCC('M', 'L', 'Y', ' '),+ KBTS_LANGUAGE_MALAYALAM = KBTS_FOURCC('M', 'A', 'L', ' '),+ KBTS_LANGUAGE_MALAYALAM_REFORMED = KBTS_FOURCC('M', 'L', 'R', ' '),+ KBTS_LANGUAGE_MALE = KBTS_FOURCC('M', 'L', 'E', ' '),+ KBTS_LANGUAGE_MALINKE = KBTS_FOURCC('M', 'L', 'N', ' '),+ KBTS_LANGUAGE_MALTESE = KBTS_FOURCC('M', 'T', 'S', ' '),+ KBTS_LANGUAGE_MAM = KBTS_FOURCC('M', 'A', 'M', ' '),+ KBTS_LANGUAGE_MANCHU = KBTS_FOURCC('M', 'C', 'H', ' '),+ KBTS_LANGUAGE_MANDAR = KBTS_FOURCC('M', 'D', 'R', ' '),+ KBTS_LANGUAGE_MANDINKA = KBTS_FOURCC('M', 'N', 'D', ' '),+ KBTS_LANGUAGE_MANINKA = KBTS_FOURCC('M', 'N', 'K', ' '),+ KBTS_LANGUAGE_MANIPURI = KBTS_FOURCC('M', 'N', 'I', ' '),+ KBTS_LANGUAGE_MANO = KBTS_FOURCC('M', 'E', 'V', ' '),+ KBTS_LANGUAGE_MANSI = KBTS_FOURCC('M', 'A', 'N', ' '),+ KBTS_LANGUAGE_MANX = KBTS_FOURCC('M', 'N', 'X', ' '),+ KBTS_LANGUAGE_MAORI = KBTS_FOURCC('M', 'R', 'I', ' '),+ KBTS_LANGUAGE_MAPUDUNGUN = KBTS_FOURCC('M', 'A', 'P', ' '),+ KBTS_LANGUAGE_MARATHI = KBTS_FOURCC('M', 'A', 'R', ' '),+ KBTS_LANGUAGE_MARSHALLESE = KBTS_FOURCC('M', 'A', 'H', ' '),+ KBTS_LANGUAGE_MARWARI = KBTS_FOURCC('M', 'A', 'W', ' '),+ KBTS_LANGUAGE_MAYAN = KBTS_FOURCC('M', 'Y', 'N', ' '),+ KBTS_LANGUAGE_MAZANDERANI = KBTS_FOURCC('M', 'Z', 'N', ' '),+ KBTS_LANGUAGE_MBEMBE_TIGON = KBTS_FOURCC('N', 'Z', 'A', ' '),+ KBTS_LANGUAGE_MBO = KBTS_FOURCC('M', 'B', 'O', ' '),+ KBTS_LANGUAGE_MBUNDU = KBTS_FOURCC('M', 'B', 'N', ' '),+ KBTS_LANGUAGE_MEDUMBA = KBTS_FOURCC('B', 'Y', 'V', ' '),+ KBTS_LANGUAGE_MEEN = KBTS_FOURCC('M', 'E', 'N', ' '),+ KBTS_LANGUAGE_MENDE = KBTS_FOURCC('M', 'D', 'E', ' '),+ KBTS_LANGUAGE_MERU = KBTS_FOURCC('M', 'E', 'R', ' '),+ KBTS_LANGUAGE_MEWATI = KBTS_FOURCC('W', 'T', 'M', ' '),+ KBTS_LANGUAGE_MINANGKABAU = KBTS_FOURCC('M', 'I', 'N', ' '),+ KBTS_LANGUAGE_MINJANGBAL = KBTS_FOURCC('X', 'J', 'B', ' '),+ KBTS_LANGUAGE_MIRANDESE = KBTS_FOURCC('M', 'W', 'L', ' '),+ KBTS_LANGUAGE_MIZO = KBTS_FOURCC('M', 'I', 'Z', ' '),+ KBTS_LANGUAGE_MOHAWK = KBTS_FOURCC('M', 'O', 'H', ' '),+ KBTS_LANGUAGE_MOKSHA = KBTS_FOURCC('M', 'O', 'K', ' '),+ KBTS_LANGUAGE_MOLDAVIAN = KBTS_FOURCC('M', 'O', 'L', ' '),+ KBTS_LANGUAGE_MON = KBTS_FOURCC('M', 'O', 'N', ' '),+ KBTS_LANGUAGE_MONGOLIAN = KBTS_FOURCC('M', 'N', 'G', ' '),+ KBTS_LANGUAGE_MOOSE_CREE = KBTS_FOURCC('M', 'C', 'R', ' '),+ KBTS_LANGUAGE_MORISYEN = KBTS_FOURCC('M', 'F', 'E', ' '),+ KBTS_LANGUAGE_MOROCCAN = KBTS_FOURCC('M', 'O', 'R', ' '),+ KBTS_LANGUAGE_MOSSI = KBTS_FOURCC('M', 'P', 'S', ' '),+ KBTS_LANGUAGE_MUNDARI = KBTS_FOURCC('M', 'U', 'N', ' '),+ KBTS_LANGUAGE_MUSCOGEE = KBTS_FOURCC('M', 'U', 'S', ' '),+ KBTS_LANGUAGE_N_CREE = KBTS_FOURCC('N', 'C', 'R', ' '),+ KBTS_LANGUAGE_NAGA_ASSAMESE = KBTS_FOURCC('N', 'A', 'G', ' '),+ KBTS_LANGUAGE_NAGARI = KBTS_FOURCC('N', 'G', 'R', ' '),+ KBTS_LANGUAGE_NAHUATL = KBTS_FOURCC('N', 'A', 'H', ' '),+ KBTS_LANGUAGE_NANAI = KBTS_FOURCC('N', 'A', 'N', ' '),+ KBTS_LANGUAGE_NASKAPI = KBTS_FOURCC('N', 'A', 'S', ' '),+ KBTS_LANGUAGE_NAURUAN = KBTS_FOURCC('N', 'A', 'U', ' '),+ KBTS_LANGUAGE_NAVAJO = KBTS_FOURCC('N', 'A', 'V', ' '),+ KBTS_LANGUAGE_NDAU = KBTS_FOURCC('N', 'D', 'C', ' '),+ KBTS_LANGUAGE_NDEBELE = KBTS_FOURCC('N', 'D', 'B', ' '),+ KBTS_LANGUAGE_NDONGA = KBTS_FOURCC('N', 'D', 'G', ' '),+ KBTS_LANGUAGE_NEAPOLITAN = KBTS_FOURCC('N', 'A', 'P', ' '),+ KBTS_LANGUAGE_NEPALI = KBTS_FOURCC('N', 'E', 'P', ' '),+ KBTS_LANGUAGE_NEWARI = KBTS_FOURCC('N', 'E', 'W', ' '),+ KBTS_LANGUAGE_NGBAKA = KBTS_FOURCC('N', 'G', 'A', ' '),+ KBTS_LANGUAGE_NIGERIAN_FULFULDE = KBTS_FOURCC('F', 'U', 'V', ' '),+ KBTS_LANGUAGE_NIMADI = KBTS_FOURCC('N', 'O', 'E', ' '),+ KBTS_LANGUAGE_NISI = KBTS_FOURCC('N', 'I', 'S', ' '),+ KBTS_LANGUAGE_NIUEAN = KBTS_FOURCC('N', 'I', 'U', ' '),+ KBTS_LANGUAGE_NKO = KBTS_FOURCC('N', 'K', 'O', ' '),+ KBTS_LANGUAGE_NOGAI = KBTS_FOURCC('N', 'O', 'G', ' '),+ KBTS_LANGUAGE_NORFOLK = KBTS_FOURCC('P', 'I', 'H', ' '),+ KBTS_LANGUAGE_NORTH_SLAVEY = KBTS_FOURCC('S', 'C', 'S', ' '),+ KBTS_LANGUAGE_NORTHERN_EMBERA = KBTS_FOURCC('E', 'M', 'P', ' '),+ KBTS_LANGUAGE_NORTHERN_SAMI = KBTS_FOURCC('N', 'S', 'M', ' '),+ KBTS_LANGUAGE_NORTHERN_SOTHO = KBTS_FOURCC('N', 'S', 'O', ' '),+ KBTS_LANGUAGE_NORTHERN_TAI = KBTS_FOURCC('N', 'T', 'A', ' '),+ KBTS_LANGUAGE_NORWAY_HOUSE_CREE = KBTS_FOURCC('N', 'H', 'C', ' '),+ KBTS_LANGUAGE_NORWEGIAN = KBTS_FOURCC('N', 'O', 'R', ' '),+ KBTS_LANGUAGE_NORWEGIAN_NYNORSK = KBTS_FOURCC('N', 'Y', 'N', ' '),+ KBTS_LANGUAGE_NOVIAL = KBTS_FOURCC('N', 'O', 'V', ' '),+ KBTS_LANGUAGE_NUMANGGANG = KBTS_FOURCC('N', 'O', 'P', ' '),+ KBTS_LANGUAGE_NUNAVIK_INUKTITUT = KBTS_FOURCC('I', 'N', 'U', ' '),+ KBTS_LANGUAGE_NUU_CHAH_NULTH = KBTS_FOURCC('N', 'U', 'K', ' '),+ KBTS_LANGUAGE_NYAMWEZI = KBTS_FOURCC('N', 'Y', 'M', ' '),+ KBTS_LANGUAGE_NYANKOLE = KBTS_FOURCC('N', 'K', 'L', ' '),+ KBTS_LANGUAGE_OCCITAN = KBTS_FOURCC('O', 'C', 'I', ' '),+ KBTS_LANGUAGE_ODIA = KBTS_FOURCC('O', 'R', 'I', ' '),+ KBTS_LANGUAGE_OJI_CREE = KBTS_FOURCC('O', 'C', 'R', ' '),+ KBTS_LANGUAGE_OJIBWAY = KBTS_FOURCC('O', 'J', 'B', ' '),+ KBTS_LANGUAGE_OLD_IRISH = KBTS_FOURCC('S', 'G', 'A', ' '),+ KBTS_LANGUAGE_OLD_JAVANESE = KBTS_FOURCC('K', 'A', 'W', ' '),+ KBTS_LANGUAGE_ONEIDA = KBTS_FOURCC('O', 'N', 'E', ' '),+ KBTS_LANGUAGE_ONONDAGA = KBTS_FOURCC('O', 'N', 'O', ' '),+ KBTS_LANGUAGE_OROMO = KBTS_FOURCC('O', 'R', 'O', ' '),+ KBTS_LANGUAGE_OSSETIAN = KBTS_FOURCC('O', 'S', 'S', ' '),+ KBTS_LANGUAGE_PA_O_KAREN = KBTS_FOURCC('B', 'L', 'K', ' '),+ KBTS_LANGUAGE_PALAUAN = KBTS_FOURCC('P', 'A', 'U', ' '),+ KBTS_LANGUAGE_PALAUNG = KBTS_FOURCC('P', 'L', 'G', ' '),+ KBTS_LANGUAGE_PALESTINIAN_ARAMAIC = KBTS_FOURCC('P', 'A', 'A', ' '),+ KBTS_LANGUAGE_PALI = KBTS_FOURCC('P', 'A', 'L', ' '),+ KBTS_LANGUAGE_PALPA = KBTS_FOURCC('P', 'A', 'P', ' '),+ KBTS_LANGUAGE_PAMPANGAN = KBTS_FOURCC('P', 'A', 'M', ' '),+ KBTS_LANGUAGE_PANGASINAN = KBTS_FOURCC('P', 'A', 'G', ' '),+ KBTS_LANGUAGE_PAPIAMENTU = KBTS_FOURCC('P', 'A', 'P', '0'),+ KBTS_LANGUAGE_PASHTO = KBTS_FOURCC('P', 'A', 'S', ' '),+ KBTS_LANGUAGE_PATTANI_MALAY = KBTS_FOURCC('M', 'F', 'A', ' '),+ KBTS_LANGUAGE_PENNSYLVANIA_GERMAN = KBTS_FOURCC('P', 'D', 'C', ' '),+ KBTS_LANGUAGE_PERSIAN = KBTS_FOURCC('F', 'A', 'R', ' '),+ KBTS_LANGUAGE_PHAKE = KBTS_FOURCC('P', 'J', 'K', ' '),+ KBTS_LANGUAGE_PICARD = KBTS_FOURCC('P', 'C', 'D', ' '),+ KBTS_LANGUAGE_PIEMONTESE = KBTS_FOURCC('P', 'M', 'S', ' '),+ KBTS_LANGUAGE_PILAGA = KBTS_FOURCC('P', 'L', 'G', ' '),+ KBTS_LANGUAGE_PITE_SAMI = KBTS_FOURCC('S', 'J', 'E', ' '),+ KBTS_LANGUAGE_POCOMCHI = KBTS_FOURCC('P', 'O', 'H', ' '),+ KBTS_LANGUAGE_POHNPEIAN = KBTS_FOURCC('P', 'O', 'N', ' '),+ KBTS_LANGUAGE_POLISH = KBTS_FOURCC('P', 'L', 'K', ' '),+ KBTS_LANGUAGE_POLYTONIC_GREEK = KBTS_FOURCC('P', 'G', 'R', ' '),+ KBTS_LANGUAGE_PORTUGUESE = KBTS_FOURCC('P', 'T', 'G', ' '),+ KBTS_LANGUAGE_PROVENCAL = KBTS_FOURCC('P', 'R', 'O', ' '),+ KBTS_LANGUAGE_PUNJABI = KBTS_FOURCC('P', 'A', 'N', ' '),+ KBTS_LANGUAGE_QUECHUA = KBTS_FOURCC('Q', 'U', 'Z', ' '),+ KBTS_LANGUAGE_QUECHUA_BOLIVIA = KBTS_FOURCC('Q', 'U', 'H', ' '),+ KBTS_LANGUAGE_QUECHUA_ECUADOR = KBTS_FOURCC('Q', 'V', 'I', ' '),+ KBTS_LANGUAGE_QUECHUA_PERU = KBTS_FOURCC('Q', 'W', 'H', ' '),+ KBTS_LANGUAGE_R_CREE = KBTS_FOURCC('R', 'C', 'R', ' '),+ KBTS_LANGUAGE_RAJASTHANI = KBTS_FOURCC('R', 'A', 'J', ' '),+ KBTS_LANGUAGE_RAKHINE = KBTS_FOURCC('A', 'R', 'K', ' '),+ KBTS_LANGUAGE_RAROTONGAN = KBTS_FOURCC('R', 'A', 'R', ' '),+ KBTS_LANGUAGE_REJANG = KBTS_FOURCC('R', 'E', 'J', ' '),+ KBTS_LANGUAGE_RIANG = KBTS_FOURCC('R', 'I', 'A', ' '),+ KBTS_LANGUAGE_RIPUARIAN = KBTS_FOURCC('K', 'S', 'H', ' '),+ KBTS_LANGUAGE_RITARUNGO = KBTS_FOURCC('R', 'I', 'T', ' '),+ KBTS_LANGUAGE_ROHINGYA = KBTS_FOURCC('R', 'H', 'G', ' '),+ KBTS_LANGUAGE_ROMANIAN = KBTS_FOURCC('R', 'O', 'M', ' '),+ KBTS_LANGUAGE_ROMANSH = KBTS_FOURCC('R', 'M', 'S', ' '),+ KBTS_LANGUAGE_ROMANY = KBTS_FOURCC('R', 'O', 'Y', ' '),+ KBTS_LANGUAGE_ROTUMAN = KBTS_FOURCC('R', 'T', 'M', ' '),+ KBTS_LANGUAGE_RUNDI = KBTS_FOURCC('R', 'U', 'N', ' '),+ KBTS_LANGUAGE_RUSSIAN = KBTS_FOURCC('R', 'U', 'S', ' '),+ KBTS_LANGUAGE_RUSSIAN_BURIAT = KBTS_FOURCC('R', 'B', 'U', ' '),+ KBTS_LANGUAGE_RUSYN = KBTS_FOURCC('R', 'S', 'Y', ' '),+ KBTS_LANGUAGE_SADRI = KBTS_FOURCC('S', 'A', 'D', ' '),+ KBTS_LANGUAGE_SAKHA = KBTS_FOURCC('Y', 'A', 'K', ' '),+ KBTS_LANGUAGE_SAMOAN = KBTS_FOURCC('S', 'M', 'O', ' '),+ KBTS_LANGUAGE_SAMOGITIAN = KBTS_FOURCC('S', 'G', 'S', ' '),+ KBTS_LANGUAGE_SAN_BLAS_KUNA = KBTS_FOURCC('C', 'U', 'K', ' '),+ KBTS_LANGUAGE_SANGO = KBTS_FOURCC('S', 'G', 'O', ' '),+ KBTS_LANGUAGE_SANSKRIT = KBTS_FOURCC('S', 'A', 'N', ' '),+ KBTS_LANGUAGE_SANTALI = KBTS_FOURCC('S', 'A', 'T', ' '),+ KBTS_LANGUAGE_SARAIKI = KBTS_FOURCC('S', 'R', 'K', ' '),+ KBTS_LANGUAGE_SARDINIAN = KBTS_FOURCC('S', 'R', 'D', ' '),+ KBTS_LANGUAGE_SASAK = KBTS_FOURCC('S', 'A', 'S', ' '),+ KBTS_LANGUAGE_SATERLAND_FRISIAN = KBTS_FOURCC('S', 'T', 'Q', ' '),+ KBTS_LANGUAGE_SAYISI = KBTS_FOURCC('S', 'A', 'Y', ' '),+ KBTS_LANGUAGE_SCOTS = KBTS_FOURCC('S', 'C', 'I', ' '),+ KBTS_LANGUAGE_SCOTTISH_GAELIC = KBTS_FOURCC('G', 'A', 'E', ' '),+ KBTS_LANGUAGE_SEKOTA = KBTS_FOURCC('S', 'E', 'J', ' '),+ KBTS_LANGUAGE_SELKUP = KBTS_FOURCC('S', 'E', 'L', ' '),+ KBTS_LANGUAGE_SENA = KBTS_FOURCC('S', 'N', 'A', ' '),+ KBTS_LANGUAGE_SENECA = KBTS_FOURCC('S', 'E', 'E', ' '),+ KBTS_LANGUAGE_SERBIAN = KBTS_FOURCC('S', 'R', 'B', ' '),+ KBTS_LANGUAGE_SERER = KBTS_FOURCC('S', 'R', 'R', ' '),+ KBTS_LANGUAGE_SGAW_KAREN = KBTS_FOURCC('K', 'S', 'W', ' '),+ KBTS_LANGUAGE_SHAN = KBTS_FOURCC('S', 'H', 'N', ' '),+ KBTS_LANGUAGE_SHONA = KBTS_FOURCC('S', 'N', 'A', ' '),+ KBTS_LANGUAGE_SIBE = KBTS_FOURCC('S', 'I', 'B', ' '),+ KBTS_LANGUAGE_SICILIAN = KBTS_FOURCC('S', 'C', 'N', ' '),+ KBTS_LANGUAGE_SIDAMO = KBTS_FOURCC('S', 'I', 'D', ' '),+ KBTS_LANGUAGE_SILESIAN = KBTS_FOURCC('S', 'Z', 'L', ' '),+ KBTS_LANGUAGE_SILTE_GURAGE = KBTS_FOURCC('S', 'I', 'G', ' '),+ KBTS_LANGUAGE_SINDHI = KBTS_FOURCC('S', 'N', 'D', ' '),+ KBTS_LANGUAGE_SINHALA = KBTS_FOURCC('S', 'N', 'H', ' '),+ KBTS_LANGUAGE_SKOLT_SAMI = KBTS_FOURCC('S', 'K', 'S', ' '),+ KBTS_LANGUAGE_SLAVEY = KBTS_FOURCC('S', 'L', 'A', ' '),+ KBTS_LANGUAGE_SLOVAK = KBTS_FOURCC('S', 'K', 'Y', ' '),+ KBTS_LANGUAGE_SLOVENIAN = KBTS_FOURCC('S', 'L', 'V', ' '),+ KBTS_LANGUAGE_SMALL_FLOWERY_MIAO = KBTS_FOURCC('S', 'F', 'M', ' '),+ KBTS_LANGUAGE_SODO_GURAGE = KBTS_FOURCC('S', 'O', 'G', ' '),+ KBTS_LANGUAGE_SOGA = KBTS_FOURCC('X', 'O', 'G', ' '),+ KBTS_LANGUAGE_SOMALI = KBTS_FOURCC('S', 'M', 'L', ' '),+ KBTS_LANGUAGE_SONGE = KBTS_FOURCC('S', 'O', 'P', ' '),+ KBTS_LANGUAGE_SONINKE = KBTS_FOURCC('S', 'N', 'K', ' '),+ KBTS_LANGUAGE_SOUTH_SLAVEY = KBTS_FOURCC('S', 'S', 'L', ' '),+ KBTS_LANGUAGE_SOUTHERN_KIWAI = KBTS_FOURCC('K', 'J', 'D', ' '),+ KBTS_LANGUAGE_SOUTHERN_SAMI = KBTS_FOURCC('S', 'S', 'M', ' '),+ KBTS_LANGUAGE_SOUTHERN_SOTHO = KBTS_FOURCC('S', 'O', 'T', ' '),+ KBTS_LANGUAGE_SPANISH = KBTS_FOURCC('E', 'S', 'P', ' '),+ KBTS_LANGUAGE_STANDARD_MOROCCAN_TAMAZIGHT = KBTS_FOURCC('Z', 'G', 'H', ' '),+ KBTS_LANGUAGE_STRAITS_SALISH = KBTS_FOURCC('S', 'T', 'R', ' '),+ KBTS_LANGUAGE_SUKUMA = KBTS_FOURCC('S', 'U', 'K', ' '),+ KBTS_LANGUAGE_SUNDANESE = KBTS_FOURCC('S', 'U', 'N', ' '),+ KBTS_LANGUAGE_SURI = KBTS_FOURCC('S', 'U', 'R', ' '),+ KBTS_LANGUAGE_SUTU = KBTS_FOURCC('S', 'X', 'T', ' '),+ KBTS_LANGUAGE_SVAN = KBTS_FOURCC('S', 'V', 'A', ' '),+ KBTS_LANGUAGE_SWADAYA_ARAMAIC = KBTS_FOURCC('S', 'W', 'A', ' '),+ KBTS_LANGUAGE_SWAHILI = KBTS_FOURCC('S', 'W', 'K', ' '),+ KBTS_LANGUAGE_SWATI = KBTS_FOURCC('S', 'W', 'Z', ' '),+ KBTS_LANGUAGE_SWEDISH = KBTS_FOURCC('S', 'V', 'E', ' '),+ KBTS_LANGUAGE_SYLHETI = KBTS_FOURCC('S', 'Y', 'L', ' '),+ KBTS_LANGUAGE_SYRIAC = KBTS_FOURCC('S', 'Y', 'R', ' '),+ KBTS_LANGUAGE_SYRIAC_EASTERN = KBTS_FOURCC('S', 'Y', 'R', 'N'),+ KBTS_LANGUAGE_SYRIAC_ESTRANGELA = KBTS_FOURCC('S', 'Y', 'R', 'E'),+ KBTS_LANGUAGE_SYRIAC_WESTERN = KBTS_FOURCC('S', 'Y', 'R', 'J'),+ KBTS_LANGUAGE_TABASARAN = KBTS_FOURCC('T', 'A', 'B', ' '),+ KBTS_LANGUAGE_TACHELHIT = KBTS_FOURCC('S', 'H', 'I', ' '),+ KBTS_LANGUAGE_TAGALOG = KBTS_FOURCC('T', 'G', 'L', ' '),+ KBTS_LANGUAGE_TAHAGGART_TAMAHAQ = KBTS_FOURCC('T', 'H', 'V', ' '),+ KBTS_LANGUAGE_TAHITIAN = KBTS_FOURCC('T', 'H', 'T', ' '),+ KBTS_LANGUAGE_TAI_LAING = KBTS_FOURCC('T', 'J', 'L', ' '),+ KBTS_LANGUAGE_TAJIKI = KBTS_FOURCC('T', 'A', 'J', ' '),+ KBTS_LANGUAGE_TALYSH = KBTS_FOURCC('T', 'L', 'Y', ' '),+ KBTS_LANGUAGE_TAMASHEK = KBTS_FOURCC('T', 'M', 'H', ' '),+ KBTS_LANGUAGE_TAMASHEQ = KBTS_FOURCC('T', 'A', 'Q', ' '),+ KBTS_LANGUAGE_TAMAZIGHT = KBTS_FOURCC('T', 'Z', 'M', ' '),+ KBTS_LANGUAGE_TAMIL = KBTS_FOURCC('T', 'A', 'M', ' '),+ KBTS_LANGUAGE_TARIFIT = KBTS_FOURCC('R', 'I', 'F', ' '),+ KBTS_LANGUAGE_TATAR = KBTS_FOURCC('T', 'A', 'T', ' '),+ KBTS_LANGUAGE_TAWALLAMMAT_TAMAJAQ = KBTS_FOURCC('T', 'T', 'Q', ' '),+ KBTS_LANGUAGE_TAY = KBTS_FOURCC('T', 'Y', 'Z', ' '),+ KBTS_LANGUAGE_TAYART_TAMAJEQ = KBTS_FOURCC('T', 'H', 'Z', ' '),+ KBTS_LANGUAGE_TELUGU = KBTS_FOURCC('T', 'E', 'L', ' '),+ KBTS_LANGUAGE_TEMNE = KBTS_FOURCC('T', 'M', 'N', ' '),+ KBTS_LANGUAGE_TETUM = KBTS_FOURCC('T', 'E', 'T', ' '),+ KBTS_LANGUAGE_TH_CREE = KBTS_FOURCC('T', 'C', 'R', ' '),+ KBTS_LANGUAGE_THAI = KBTS_FOURCC('T', 'H', 'A', ' '),+ KBTS_LANGUAGE_THAILAND_MON = KBTS_FOURCC('M', 'O', 'N', 'T'),+ KBTS_LANGUAGE_THOMPSON = KBTS_FOURCC('T', 'H', 'P', ' '),+ KBTS_LANGUAGE_TIBETAN = KBTS_FOURCC('T', 'I', 'B', ' '),+ KBTS_LANGUAGE_TIGRE = KBTS_FOURCC('T', 'G', 'R', ' '),+ KBTS_LANGUAGE_TIGRINYA = KBTS_FOURCC('T', 'G', 'Y', ' '),+ KBTS_LANGUAGE_TIV = KBTS_FOURCC('T', 'I', 'V', ' '),+ KBTS_LANGUAGE_TLINGIT = KBTS_FOURCC('T', 'L', 'I', ' '),+ KBTS_LANGUAGE_TOBO = KBTS_FOURCC('T', 'B', 'V', ' '),+ KBTS_LANGUAGE_TODO = KBTS_FOURCC('T', 'O', 'D', ' '),+ KBTS_LANGUAGE_TOK_PISIN = KBTS_FOURCC('T', 'P', 'I', ' '),+ KBTS_LANGUAGE_TOMA = KBTS_FOURCC('T', 'O', 'D', '0'),+ KBTS_LANGUAGE_TONGA = KBTS_FOURCC('T', 'N', 'G', ' '),+ KBTS_LANGUAGE_TONGAN = KBTS_FOURCC('T', 'G', 'N', ' '),+ KBTS_LANGUAGE_TORKI = KBTS_FOURCC('A', 'Z', 'B', ' '),+ KBTS_LANGUAGE_TSHANGLA = KBTS_FOURCC('T', 'S', 'J', ' '),+ KBTS_LANGUAGE_TSONGA = KBTS_FOURCC('T', 'S', 'G', ' '),+ KBTS_LANGUAGE_TSWANA = KBTS_FOURCC('T', 'N', 'A', ' '),+ KBTS_LANGUAGE_TULU = KBTS_FOURCC('T', 'U', 'L', ' '),+ KBTS_LANGUAGE_TUMBUKA = KBTS_FOURCC('T', 'U', 'M', ' '),+ KBTS_LANGUAGE_TUNDRA_ENETS = KBTS_FOURCC('T', 'N', 'E', ' '),+ KBTS_LANGUAGE_TURKISH = KBTS_FOURCC('T', 'R', 'K', ' '),+ KBTS_LANGUAGE_TURKMEN = KBTS_FOURCC('T', 'K', 'M', ' '),+ KBTS_LANGUAGE_TUROYO_ARAMAIC = KBTS_FOURCC('T', 'U', 'A', ' '),+ KBTS_LANGUAGE_TUSCARORA = KBTS_FOURCC('T', 'U', 'S', ' '),+ KBTS_LANGUAGE_TUVALU = KBTS_FOURCC('T', 'V', 'L', ' '),+ KBTS_LANGUAGE_TUVIN = KBTS_FOURCC('T', 'U', 'V', ' '),+ KBTS_LANGUAGE_TWI = KBTS_FOURCC('T', 'W', 'I', ' '),+ KBTS_LANGUAGE_TZOTZIL = KBTS_FOURCC('T', 'Z', 'O', ' '),+ KBTS_LANGUAGE_UDI = KBTS_FOURCC('U', 'D', 'I', ' '),+ KBTS_LANGUAGE_UDMURT = KBTS_FOURCC('U', 'D', 'M', ' '),+ KBTS_LANGUAGE_UKRAINIAN = KBTS_FOURCC('U', 'K', 'R', ' '),+ KBTS_LANGUAGE_UMBUNDU = KBTS_FOURCC('U', 'M', 'B', ' '),+ KBTS_LANGUAGE_UME_SAMI = KBTS_FOURCC('S', 'J', 'U', ' '),+ KBTS_LANGUAGE_UPPER_SAXON = KBTS_FOURCC('S', 'X', 'U', ' '),+ KBTS_LANGUAGE_UPPER_SORBIAN = KBTS_FOURCC('U', 'S', 'B', ' '),+ KBTS_LANGUAGE_URALIC_PHONETIC = KBTS_FOURCC('U', 'P', 'P', ' '),+ KBTS_LANGUAGE_URDU = KBTS_FOURCC('U', 'R', 'D', ' '),+ KBTS_LANGUAGE_UYGHUR = KBTS_FOURCC('U', 'Y', 'G', ' '),+ KBTS_LANGUAGE_UZBEK = KBTS_FOURCC('U', 'Z', 'B', ' '),+ KBTS_LANGUAGE_VENDA = KBTS_FOURCC('V', 'E', 'N', ' '),+ KBTS_LANGUAGE_VENETIAN = KBTS_FOURCC('V', 'E', 'C', ' '),+ KBTS_LANGUAGE_VIETNAMESE = KBTS_FOURCC('V', 'I', 'T', ' '),+ KBTS_LANGUAGE_VLAX_ROMANI = KBTS_FOURCC('R', 'M', 'Y', ' '),+ KBTS_LANGUAGE_VOLAPUK = KBTS_FOURCC('V', 'O', 'L', ' '),+ KBTS_LANGUAGE_VORO = KBTS_FOURCC('V', 'R', 'O', ' '),+ KBTS_LANGUAGE_WA = KBTS_FOURCC('W', 'A', ' ', ' '),+ KBTS_LANGUAGE_WACI_GBE = KBTS_FOURCC('W', 'C', 'I', ' '),+ KBTS_LANGUAGE_WAGDI = KBTS_FOURCC('W', 'A', 'G', ' '),+ KBTS_LANGUAGE_WAKHI = KBTS_FOURCC('W', 'B', 'L', ' '),+ KBTS_LANGUAGE_WALLOON = KBTS_FOURCC('W', 'L', 'N', ' '),+ KBTS_LANGUAGE_WARAY_WARAY = KBTS_FOURCC('W', 'A', 'R', ' '),+ KBTS_LANGUAGE_WAYANAD_CHETTI = KBTS_FOURCC('C', 'T', 'T', ' '),+ KBTS_LANGUAGE_WAYUU = KBTS_FOURCC('G', 'U', 'C', ' '),+ KBTS_LANGUAGE_WELSH = KBTS_FOURCC('W', 'E', 'L', ' '),+ KBTS_LANGUAGE_WENDAT = KBTS_FOURCC('W', 'D', 'T', ' '),+ KBTS_LANGUAGE_WEST_CREE = KBTS_FOURCC('W', 'C', 'R', ' '),+ KBTS_LANGUAGE_WESTERN_CHAM = KBTS_FOURCC('C', 'J', 'A', ' '),+ KBTS_LANGUAGE_WESTERN_KAYAH = KBTS_FOURCC('K', 'Y', 'U', ' '),+ KBTS_LANGUAGE_WESTERN_PANJABI = KBTS_FOURCC('P', 'N', 'B', ' '),+ KBTS_LANGUAGE_WESTERN_PWO_KAREN = KBTS_FOURCC('P', 'W', 'O', ' '),+ KBTS_LANGUAGE_WOLOF = KBTS_FOURCC('W', 'L', 'F', ' '),+ KBTS_LANGUAGE_WOODS_CREE = KBTS_FOURCC('D', 'C', 'R', ' '),+ KBTS_LANGUAGE_WUDING_LUQUAN_YI = KBTS_FOURCC('Y', 'W', 'Q', ' '),+ KBTS_LANGUAGE_WYANDOT = KBTS_FOURCC('W', 'Y', 'N', ' '),+ KBTS_LANGUAGE_XHOSA = KBTS_FOURCC('X', 'H', 'S', ' '),+ KBTS_LANGUAGE_Y_CREE = KBTS_FOURCC('Y', 'C', 'R', ' '),+ KBTS_LANGUAGE_YAO = KBTS_FOURCC('Y', 'A', 'O', ' '),+ KBTS_LANGUAGE_YAPESE = KBTS_FOURCC('Y', 'A', 'P', ' '),+ KBTS_LANGUAGE_YI_CLASSIC = KBTS_FOURCC('Y', 'I', 'C', ' '),+ KBTS_LANGUAGE_YI_MODERN = KBTS_FOURCC('Y', 'I', 'M', ' '),+ KBTS_LANGUAGE_YIDDISH = KBTS_FOURCC('J', 'I', 'I', ' '),+ KBTS_LANGUAGE_YORUBA = KBTS_FOURCC('Y', 'B', 'A', ' '),+ KBTS_LANGUAGE_ZAMBOANGA_CHAVACANO = KBTS_FOURCC('C', 'B', 'K', ' '),+ KBTS_LANGUAGE_ZANDE = KBTS_FOURCC('Z', 'N', 'D', ' '),+ KBTS_LANGUAGE_ZARMA = KBTS_FOURCC('D', 'J', 'R', ' '),+ KBTS_LANGUAGE_ZAZAKI = KBTS_FOURCC('Z', 'Z', 'A', ' '),+ KBTS_LANGUAGE_ZEALANDIC = KBTS_FOURCC('Z', 'E', 'A', ' '),+ KBTS_LANGUAGE_ZHUANG = KBTS_FOURCC('Z', 'H', 'A', ' '),+ KBTS_LANGUAGE_ZULU = KBTS_FOURCC('Z', 'U', 'L', ' '),+};++typedef kbts_u32 kbts_break_flags;+enum kbts_break_flags_enum+{+ // Direction changes from left-to-right to right-to-left, or vice versa.+ KBTS_BREAK_FLAG_DIRECTION = 1 << 0,+ // Script changes.+ // Note that some characters, such as digits, are used in multiple+ // scripts and, as such, will not produce script breaks.+ KBTS_BREAK_FLAG_SCRIPT = 1 << 1,+ // Graphemes are "visual units". They may be composed of more than one codepoint.+ // They are used as interaction boundaries in graphical interfaces, e.g. moving the+ // caret.+ KBTS_BREAK_FLAG_GRAPHEME = 1 << 2,+ // In most scripts, words are broken up by whitespace, but Unicode word breaking has+ // better script coverage and also handles some special cases that a simple stateless+ // loop cannot handle.+ KBTS_BREAK_FLAG_WORD = 1 << 3,+ // By default, you are not allowed to break a line.+ // Soft line breaks allow for line breaking, but do not require it.+ // This is useful for when you are doing line wrapping.+ KBTS_BREAK_FLAG_LINE_SOFT = 1 << 4,+ // Hard line breaks are required. They signal the end of a paragraph.+ // (In Unicode, there is no meaningful distinction between a line and a paragraph.+ // a paragraph is pretty much just a line of text that can wrap.)+ KBTS_BREAK_FLAG_LINE_HARD = 1 << 5,+ // Used for manual segmentation in the context.+ KBTS_BREAK_FLAG_MANUAL = 1 << 6,++ KBTS_BREAK_FLAG_PARAGRAPH_DIRECTION = 1 << 7,++ KBTS_BREAK_FLAG_LINE = KBTS_BREAK_FLAG_LINE_SOFT | KBTS_BREAK_FLAG_LINE_HARD,+ KBTS_BREAK_FLAG_ANY = KBTS_BREAK_FLAG_DIRECTION | KBTS_BREAK_FLAG_SCRIPT | KBTS_BREAK_FLAG_GRAPHEME | KBTS_BREAK_FLAG_WORD | KBTS_BREAK_FLAG_LINE_SOFT | KBTS_BREAK_FLAG_LINE_HARD,+};++// Japanese text contains "kinsoku" characters, around which breaking a line is forbidden.+// Exactly which characters are "kinsoku" or not depends on the context:+// - Strict style has the largest amount of kinsoku characters, which leads to longer lines.+// - Loose style has the smallest amount of kinsoku characters, which leads to smaller lines.+// - Normal style is somewhere in the middle.+// Note that, while the Unicode standard mentions all three of these styles, it does not mention+// any differences between the normal and loose styles.+// As such, normal and loose styles currently behave the same.+typedef kbts_u8 kbts_japanese_line_break_style;+enum kbts_japanese_line_break_style_enum+{+ // The Unicode standard does not define what strict style is used for.+ // Supposedly, it is used for anything that does not fall into the other two categories of text.+ KBTS_JAPANESE_LINE_BREAK_STYLE_STRICT,++ // Normal style is used for books and documents.+ KBTS_JAPANESE_LINE_BREAK_STYLE_NORMAL,++ // Loose style is used for newspapers, and (I assume) any other narrow column format.+ KBTS_JAPANESE_LINE_BREAK_STYLE_LOOSE,++ KBTS_JAPANESE_LINE_BREAK_STYLE_COUNT,+};++typedef kbts_u32 kbts_break_state_flags;+enum kbts_break_state_flags_enum+{+ KBTS_BREAK_STATE_FLAG_STARTED = 1,+ KBTS_BREAK_STATE_FLAG_END = 2,++ // Bidirectional flags+ KBTS_BREAK_STATE_FLAG_SAW_R_AFTER_L = 8,+ KBTS_BREAK_STATE_FLAG_SAW_AL_AFTER_LR = 0x10,+ KBTS_BREAK_STATE_FLAG_LAST_WAS_BRACKET = 0x20,+};++typedef kbts_u32 kbts_text_format;+enum kbts_text_format_enum+{+ KBTS_TEXT_FORMAT_NONE,++ KBTS_TEXT_FORMAT_UTF32,+ KBTS_TEXT_FORMAT_UTF8,++ KBTS_TEXT_FORMAT_COUNT,+};++typedef kbts_u32 kbts_direction;+enum kbts_direction_enum+{+ KBTS_DIRECTION_DONT_KNOW,+ KBTS_DIRECTION_LTR,+ KBTS_DIRECTION_RTL,++ KBTS_DIRECTION_COUNT,+};++typedef kbts_u32 kbts_orientation;+enum kbts_orientation_enum+{+ KBTS_ORIENTATION_HORIZONTAL,+ KBTS_ORIENTATION_VERTICAL,++ KBTS_ORIENTATION_COUNT,+};++typedef kbts_u8 kbts_shaping_table;+enum kbts_shaping_table_enum+{+ KBTS_SHAPING_TABLE_GSUB,+ KBTS_SHAPING_TABLE_GPOS,+ KBTS_SHAPING_TABLE_COUNT,+};++typedef kbts_u32 kbts_shape_error;+enum kbts_shape_error_enum+{+ KBTS_SHAPE_ERROR_NONE,+ KBTS_SHAPE_ERROR_INVALID_FONT,+ KBTS_SHAPE_ERROR_GAVE_TEXT_BEFORE_CALLING_BEGIN,+ KBTS_SHAPE_ERROR_OUT_OF_MEMORY,++ KBTS_SHAPE_ERROR_COUNT,+};++typedef kbts_u32 kbts_allocator_op_kind;+enum kbts_allocator_op_kind_enum+{+ KBTS_ALLOCATOR_OP_KIND_NONE,+ KBTS_ALLOCATOR_OP_KIND_ALLOCATE,+ KBTS_ALLOCATOR_OP_KIND_FREE,++ KBTS_ALLOCATOR_OP_KIND_COUNT,+};++typedef kbts_u32 kbts_blob_table_id;+enum kbts_blob_table_id_enum+{+ KBTS_BLOB_TABLE_ID_NONE,+ KBTS_BLOB_TABLE_ID_HEAD,+ KBTS_BLOB_TABLE_ID_CMAP,+ KBTS_BLOB_TABLE_ID_GDEF,+ KBTS_BLOB_TABLE_ID_GSUB,+ KBTS_BLOB_TABLE_ID_GPOS,+ KBTS_BLOB_TABLE_ID_HHEA,+ KBTS_BLOB_TABLE_ID_VHEA,+ KBTS_BLOB_TABLE_ID_HMTX,+ KBTS_BLOB_TABLE_ID_VMTX,+ KBTS_BLOB_TABLE_ID_MAXP,+ KBTS_BLOB_TABLE_ID_OS2,+ KBTS_BLOB_TABLE_ID_NAME,++ KBTS_BLOB_TABLE_ID_COUNT,+};++typedef kbts_u32 kbts_load_font_error;+enum kbts_load_font_error_enum+{+ KBTS_LOAD_FONT_ERROR_NONE,+ KBTS_LOAD_FONT_ERROR_NEED_TO_CREATE_BLOB,+ KBTS_LOAD_FONT_ERROR_INVALID_FONT,+ KBTS_LOAD_FONT_ERROR_OUT_OF_MEMORY,+ KBTS_LOAD_FONT_ERROR_COULD_NOT_OPEN_FILE,+ KBTS_LOAD_FONT_ERROR_READ_ERROR,++ KBTS_LOAD_FONT_ERROR_COUNT,+};++typedef kbts_u32 kbts_version;+enum kbts_version_enum+{+ KBTS_VERSION_1_X,+ KBTS_VERSION_2_0,++ KBTS_VERSION_CURRENT = KBTS_VERSION_2_0,+};++typedef kbts_u32 kbts_blob_version;+enum kbts_blob_version_enum+{+ KBTS_BLOB_VERSION_INVALID,+ KBTS_BLOB_VERSION_INITIAL,++ KBTS_BLOB_VERSION_CURRENT = KBTS_BLOB_VERSION_INITIAL,+};++typedef kbts_u32 kbts_font_style_flags;+enum kbts_font_style_flags_enum+{+ KBTS_FONT_STYLE_FLAG_NONE,++ KBTS_FONT_STYLE_FLAG_REGULAR = (1 << 0),+ KBTS_FONT_STYLE_FLAG_ITALIC = (1 << 1),+ KBTS_FONT_STYLE_FLAG_BOLD = (1 << 2),+};++typedef kbts_u32 kbts_font_weight;+enum kbts_font_weight_enum+{+ KBTS_FONT_WEIGHT_UNKNOWN,++ KBTS_FONT_WEIGHT_THIN,+ KBTS_FONT_WEIGHT_EXTRA_LIGHT,+ KBTS_FONT_WEIGHT_LIGHT,+ KBTS_FONT_WEIGHT_NORMAL,+ KBTS_FONT_WEIGHT_MEDIUM,+ KBTS_FONT_WEIGHT_SEMI_BOLD,+ KBTS_FONT_WEIGHT_BOLD,+ KBTS_FONT_WEIGHT_EXTRA_BOLD,+ KBTS_FONT_WEIGHT_BLACK,++ KBTS_FONT_WEIGHT_COUNT,+};++typedef kbts_u32 kbts_font_width;+enum kbts_font_width_enum+{+ KBTS_FONT_WIDTH_UNKNOWN,++ KBTS_FONT_WIDTH_ULTRA_CONDENSED,+ KBTS_FONT_WIDTH_EXTRA_CONDENSED,+ KBTS_FONT_WIDTH_CONDENSED,+ KBTS_FONT_WIDTH_SEMI_CONDENSED,+ KBTS_FONT_WIDTH_NORMAL,+ KBTS_FONT_WIDTH_SEMI_EXPANDED,+ KBTS_FONT_WIDTH_EXPANDED,+ KBTS_FONT_WIDTH_EXTRA_EXPANDED,+ KBTS_FONT_WIDTH_ULTRA_EXPANDED,++ KBTS_FONT_WIDTH_COUNT,+};++typedef kbts_u32 kbts_glyph_flags;+enum kbts_glyph_flags_enum+{+ // These feature flags must coincide with kbts_joining_feature _and_ KBTS_FEATURE_FLAG!+ KBTS_GLYPH_FLAG_ISOL = (1 << 0),+ KBTS_GLYPH_FLAG_FINA = (1 << 1),+ KBTS_GLYPH_FLAG_FIN2 = (1 << 2),+ KBTS_GLYPH_FLAG_FIN3 = (1 << 3),+ KBTS_GLYPH_FLAG_MEDI = (1 << 4),+ KBTS_GLYPH_FLAG_MED2 = (1 << 5),+ KBTS_GLYPH_FLAG_INIT = (1 << 6),++ // These feature flags must coincide with FEATURE_FLAG!+ KBTS_GLYPH_FLAG_LJMO = (1 << 7),+ KBTS_GLYPH_FLAG_VJMO = (1 << 8),+ KBTS_GLYPH_FLAG_TJMO = (1 << 9),+ KBTS_GLYPH_FLAG_RPHF = (1 << 10),+ KBTS_GLYPH_FLAG_BLWF = (1 << 11),+ KBTS_GLYPH_FLAG_HALF = (1 << 12),+ KBTS_GLYPH_FLAG_PSTF = (1 << 13),+ KBTS_GLYPH_FLAG_ABVF = (1 << 14),+ KBTS_GLYPH_FLAG_PREF = (1 << 15),+ KBTS_GLYPH_FLAG_NUMR = (1 << 16),+ KBTS_GLYPH_FLAG_FRAC = (1 << 17),+ KBTS_GLYPH_FLAG_DNOM = (1 << 18),+ KBTS_GLYPH_FLAG_CFAR = (1 << 19),++ // These can be anything.+ KBTS_GLYPH_FLAG_DO_NOT_DECOMPOSE = (1 << 21),+ KBTS_GLYPH_FLAG_FIRST_IN_MULTIPLE_SUBSTITUTION = (1 << 22),+ KBTS_GLYPH_FLAG_NO_BREAK = (1 << 23),+ KBTS_GLYPH_FLAG_CURSIVE = (1 << 24),+ KBTS_GLYPH_FLAG_GENERATED_BY_GSUB = (1 << 25),+ KBTS_GLYPH_FLAG_USED_IN_GPOS = (1 << 26),++ KBTS_GLYPH_FLAG_STCH_ENDPOINT = (1 << 27),+ KBTS_GLYPH_FLAG_STCH_EXTENSION = (1 << 28),++ KBTS_GLYPH_FLAG_LIGATURE = (1 << 29),+ KBTS_GLYPH_FLAG_MULTIPLE_SUBSTITUTION = (1 << 30),+};++typedef kbts_u8 kbts_joining_feature;+enum kbts_joining_feature_enum+{+ KBTS_JOINING_FEATURE_NONE,++ // These must correspond with glyph_flags and FEATURE_IDs.+ KBTS_JOINING_FEATURE_ISOL,+ KBTS_JOINING_FEATURE_FINA,+ KBTS_JOINING_FEATURE_FIN2,+ KBTS_JOINING_FEATURE_FIN3,+ KBTS_JOINING_FEATURE_MEDI,+ KBTS_JOINING_FEATURE_MED2,+ KBTS_JOINING_FEATURE_INIT,++ KBTS_JOINING_FEATURE_COUNT,+};++typedef kbts_u32 kbts_user_id_generation_mode;+enum kbts_user_id_generation_mode_enum+{+ KBTS_USER_ID_GENERATION_MODE_CODEPOINT_INDEX,+ KBTS_USER_ID_GENERATION_MODE_SOURCE_INDEX,++ KBTS_USER_ID_GENERATION_MODE_COUNT,+};++typedef kbts_u32 kbts_break_config_flags;+enum kbts_break_config_flags_enum+{+ KBTS_BREAK_CONFIG_FLAG_NONE,++ KBTS_BREAK_CONFIG_FLAG_END_OF_TEXT_GENERATES_HARD_LINE_BREAK = 1,+};++typedef kbts_u32 kbts_font_info_string_id;+enum kbts_font_info_string_id_enum+{+ KBTS_FONT_INFO_STRING_ID_NONE,+ KBTS_FONT_INFO_STRING_ID_COPYRIGHT,+ KBTS_FONT_INFO_STRING_ID_FAMILY,+ KBTS_FONT_INFO_STRING_ID_SUBFAMILY,+ KBTS_FONT_INFO_STRING_ID_UID,+ KBTS_FONT_INFO_STRING_ID_FULL_NAME,+ KBTS_FONT_INFO_STRING_ID_VERSION,+ KBTS_FONT_INFO_STRING_ID_POSTSCRIPT_NAME,+ KBTS_FONT_INFO_STRING_ID_TRADEMARK,+ KBTS_FONT_INFO_STRING_ID_MANUFACTURER,+ KBTS_FONT_INFO_STRING_ID_DESIGNER,+ KBTS_FONT_INFO_STRING_ID_TYPOGRAPHIC_FAMILY,+ KBTS_FONT_INFO_STRING_ID_TYPOGRAPHIC_SUBFAMILY,++ KBTS_FONT_INFO_STRING_ID_COUNT,+};+++typedef kbts_u8 kbts_unicode_joining_type;+enum kbts_unicode_joining_type_enum+{+ KBTS_UNICODE_JOINING_TYPE_NONE,+ KBTS_UNICODE_JOINING_TYPE_LEFT,+ KBTS_UNICODE_JOINING_TYPE_DUAL,+ KBTS_UNICODE_JOINING_TYPE_FORCE,+ KBTS_UNICODE_JOINING_TYPE_RIGHT,+ KBTS_UNICODE_JOINING_TYPE_TRANSPARENT,+ KBTS_UNICODE_JOINING_TYPE_COUNT,+};++typedef kbts_u8 kbts_unicode_flags;+enum kbts_unicode_flag_enum+{+ KBTS_UNICODE_FLAG_MODIFIER_COMBINING_MARK = (1 << 0),+ KBTS_UNICODE_FLAG_DEFAULT_IGNORABLE = (1 << 1),+ KBTS_UNICODE_FLAG_OPEN_BRACKET = (1 << 2),+ KBTS_UNICODE_FLAG_CLOSE_BRACKET = (1 << 3),+ KBTS_UNICODE_FLAG_PART_OF_WORD = (1 << 4),+ KBTS_UNICODE_FLAG_DECIMAL_DIGIT = (1 << 5),+ KBTS_UNICODE_FLAG_NON_SPACING_MARK = (1 << 6),++ KBTS_UNICODE_FLAG_MIRRORED = KBTS_UNICODE_FLAG_OPEN_BRACKET | KBTS_UNICODE_FLAG_CLOSE_BRACKET,+};++typedef kbts_u8 kbts_unicode_bidirectional_class;+enum kbts_unicode_bidirectional_class_enum+{+ KBTS_UNICODE_BIDIRECTIONAL_CLASS_NI,+ KBTS_UNICODE_BIDIRECTIONAL_CLASS_BN, // Formatting characters need to be ignored.+ KBTS_UNICODE_BIDIRECTIONAL_CLASS_L,+ KBTS_UNICODE_BIDIRECTIONAL_CLASS_R,+ KBTS_UNICODE_BIDIRECTIONAL_CLASS_NSM,+ KBTS_UNICODE_BIDIRECTIONAL_CLASS_AL,+ KBTS_UNICODE_BIDIRECTIONAL_CLASS_AN,+ KBTS_UNICODE_BIDIRECTIONAL_CLASS_EN,+ KBTS_UNICODE_BIDIRECTIONAL_CLASS_ES,+ KBTS_UNICODE_BIDIRECTIONAL_CLASS_ET,+ KBTS_UNICODE_BIDIRECTIONAL_CLASS_CS,+ KBTS_UNICODE_BIDIRECTIONAL_CLASS_COUNT,+};++typedef kbts_u8 kbts_line_break_class;+enum kbts_line_break_class_enum+{+ /* 0 */ KBTS_LINE_BREAK_CLASS_Onea,+ /* 1 */ KBTS_LINE_BREAK_CLASS_Oea,+ /* 2 */ KBTS_LINE_BREAK_CLASS_Ope,+ /* 3 */ KBTS_LINE_BREAK_CLASS_BK,+ /* 4 */ KBTS_LINE_BREAK_CLASS_CR,+ /* 5 */ KBTS_LINE_BREAK_CLASS_LF,+ /* 6 */ KBTS_LINE_BREAK_CLASS_NL,+ /* 7 */ KBTS_LINE_BREAK_CLASS_SP,+ /* 8 */ KBTS_LINE_BREAK_CLASS_ZW,+ /* 9 */ KBTS_LINE_BREAK_CLASS_WJ,+ /* 10 */ KBTS_LINE_BREAK_CLASS_GLnea,+ /* 11 */ KBTS_LINE_BREAK_CLASS_GLea,+ /* 12 */ KBTS_LINE_BREAK_CLASS_CLnea,+ /* 13 */ KBTS_LINE_BREAK_CLASS_CLea,+ /* 14 */ KBTS_LINE_BREAK_CLASS_CPnea,+ /* 15 */ KBTS_LINE_BREAK_CLASS_CPea,+ /* 16 */ KBTS_LINE_BREAK_CLASS_EXnea,+ /* 17 */ KBTS_LINE_BREAK_CLASS_EXea,+ /* 18 */ KBTS_LINE_BREAK_CLASS_SY,+ /* 19 */ KBTS_LINE_BREAK_CLASS_BAnea,+ /* 20 */ KBTS_LINE_BREAK_CLASS_BAea,+ /* 21 */ KBTS_LINE_BREAK_CLASS_OPnea,+ /* 22 */ KBTS_LINE_BREAK_CLASS_OPea,+ /* 23 */ KBTS_LINE_BREAK_CLASS_QU,+ /* 24 */ KBTS_LINE_BREAK_CLASS_QUPi,+ /* 25 */ KBTS_LINE_BREAK_CLASS_QUPf,+ /* 26 */ KBTS_LINE_BREAK_CLASS_IS,+ /* 27 */ KBTS_LINE_BREAK_CLASS_NSnea,+ /* 28 */ KBTS_LINE_BREAK_CLASS_NSea,+ /* 29 */ KBTS_LINE_BREAK_CLASS_B2,+ /* 30 */ KBTS_LINE_BREAK_CLASS_CB,+ /* 31 */ KBTS_LINE_BREAK_CLASS_HY,+ /* 32 */ KBTS_LINE_BREAK_CLASS_HYPHEN,+ /* 33 */ KBTS_LINE_BREAK_CLASS_INnea,+ /* 34 */ KBTS_LINE_BREAK_CLASS_INea,+ /* 35 */ KBTS_LINE_BREAK_CLASS_BB,+ /* 36 */ KBTS_LINE_BREAK_CLASS_HL,+ /* 37 */ KBTS_LINE_BREAK_CLASS_ALnea,+ /* 38 */ KBTS_LINE_BREAK_CLASS_ALea,+ /* 39 */ KBTS_LINE_BREAK_CLASS_NU,+ /* 40 */ KBTS_LINE_BREAK_CLASS_PRnea,+ /* 41 */ KBTS_LINE_BREAK_CLASS_PRea,+ /* 42 */ KBTS_LINE_BREAK_CLASS_IDnea,+ /* 43 */ KBTS_LINE_BREAK_CLASS_IDea,+ /* 44 */ KBTS_LINE_BREAK_CLASS_IDpe,+ /* 45 */ KBTS_LINE_BREAK_CLASS_EBnea,+ /* 46 */ KBTS_LINE_BREAK_CLASS_EBea,+ /* 47 */ KBTS_LINE_BREAK_CLASS_EM,+ /* 48 */ KBTS_LINE_BREAK_CLASS_POnea,+ /* 49 */ KBTS_LINE_BREAK_CLASS_POea,+ /* 50 */ KBTS_LINE_BREAK_CLASS_JL,+ /* 51 */ KBTS_LINE_BREAK_CLASS_JV,+ /* 52 */ KBTS_LINE_BREAK_CLASS_JT,+ /* 53 */ KBTS_LINE_BREAK_CLASS_H2,+ /* 54 */ KBTS_LINE_BREAK_CLASS_H3,+ /* 55 */ KBTS_LINE_BREAK_CLASS_AP,+ /* 56 */ KBTS_LINE_BREAK_CLASS_AK,+ /* 57 */ KBTS_LINE_BREAK_CLASS_DOTTED_CIRCLE,+ /* 58 */ KBTS_LINE_BREAK_CLASS_AS,+ /* 59 */ KBTS_LINE_BREAK_CLASS_VF,+ /* 60 */ KBTS_LINE_BREAK_CLASS_VI,+ /* 61 */ KBTS_LINE_BREAK_CLASS_RI,++ /* 62 */ KBTS_LINE_BREAK_CLASS_COUNT,++ /* 63 */ KBTS_LINE_BREAK_CLASS_CM,+ /* 64 */ KBTS_LINE_BREAK_CLASS_ZWJ,++ // CJ resolves to either NS or ID depending on the (Japanese) line break style.+ // NS is strict line breaking, used for long lines.+ // ID is normal line breaking, used for normal body text.+ /* 65 */ KBTS_LINE_BREAK_CLASS_CJ,++ /* 66 */ KBTS_LINE_BREAK_CLASS_SOT,+ /* 67 */ KBTS_LINE_BREAK_CLASS_EOT,+};++// @Cleanup: Merge EX and FO.+typedef kbts_u8 kbts_word_break_class;+enum kbts_word_break_class_enum+{+ KBTS_WORD_BREAK_CLASS_Onep,+ KBTS_WORD_BREAK_CLASS_Oep,+ KBTS_WORD_BREAK_CLASS_CR,+ KBTS_WORD_BREAK_CLASS_LF,+ KBTS_WORD_BREAK_CLASS_NL,+ KBTS_WORD_BREAK_CLASS_EX,+ KBTS_WORD_BREAK_CLASS_ZWJ,+ KBTS_WORD_BREAK_CLASS_RI,+ KBTS_WORD_BREAK_CLASS_FO,+ KBTS_WORD_BREAK_CLASS_KA,+ KBTS_WORD_BREAK_CLASS_HL,+ KBTS_WORD_BREAK_CLASS_ALnep,+ KBTS_WORD_BREAK_CLASS_ALep,+ KBTS_WORD_BREAK_CLASS_SQ,+ KBTS_WORD_BREAK_CLASS_DQ,+ KBTS_WORD_BREAK_CLASS_MNL,+ KBTS_WORD_BREAK_CLASS_ML,+ KBTS_WORD_BREAK_CLASS_MN,+ KBTS_WORD_BREAK_CLASS_NM,+ KBTS_WORD_BREAK_CLASS_ENL,+ KBTS_WORD_BREAK_CLASS_WSS,++ KBTS_WORD_BREAK_CLASS_SOT,+};++// Unicode defines scripts and languages.+// A language belongs to a single script, and a script belongs to a single writing system.+// On top of these, OpenType defines shapers, which are basically just designations for+// specific code paths that are taken depending on which script is being shapen.+//+// Some scripts, like Latin and Cyrillic, need relatively few operations, while complex+// scripts like Arabic and Indic scripts have specific processing steps that need to happen+// in order to obtain a correct result.+//+// These sequences of operations are _not_ described in the font file itself. The shaping+// code needs to know which script it is shaping, and implement all of those passes itself.+// That is why you, as a user, have to care about this.+//+// When creating shape_config, you can either pass in a known script, or you can specify+// SCRIPT_DONT_KNOW and let the library figure it out.+// While SCRIPT_DONT_KNOW may look appealing, it is worth noting that we can only infer+// the _script_, and not the language, of the text you pass in.+// This means that you might miss out on language-specific features when you use it.+typedef kbts_u32 kbts_shaper;+enum kbts_shaper_enum+{+ KBTS_SHAPER_DEFAULT,+ KBTS_SHAPER_ARABIC,+ KBTS_SHAPER_HANGUL,+ KBTS_SHAPER_HEBREW,+ KBTS_SHAPER_INDIC,+ KBTS_SHAPER_KHMER,+ KBTS_SHAPER_MYANMAR,+ KBTS_SHAPER_TIBETAN,+ KBTS_SHAPER_USE,++ KBTS_SHAPER_COUNT,+};+#define KBTS_MAXIMUM_RECOMPOSITION_PARENTS 19+#define KBTS_MAXIMUM_CODEPOINT_SCRIPTS 23+typedef kbts_u32 kbts_script_tag;+enum kbts_script_tag_enum+{+ KBTS_SCRIPT_TAG_DONT_KNOW = KBTS_FOURCC(' ', ' ', ' ', ' '),+ KBTS_SCRIPT_TAG_ADLAM = KBTS_FOURCC('a', 'd', 'l', 'm'),+ KBTS_SCRIPT_TAG_AHOM = KBTS_FOURCC('a', 'h', 'o', 'm'),+ KBTS_SCRIPT_TAG_ANATOLIAN_HIEROGLYPHS = KBTS_FOURCC('h', 'l', 'u', 'w'),+ KBTS_SCRIPT_TAG_ARABIC = KBTS_FOURCC('a', 'r', 'a', 'b'),+ KBTS_SCRIPT_TAG_ARMENIAN = KBTS_FOURCC('a', 'r', 'm', 'n'),+ KBTS_SCRIPT_TAG_AVESTAN = KBTS_FOURCC('a', 'v', 's', 't'),+ KBTS_SCRIPT_TAG_BALINESE = KBTS_FOURCC('b', 'a', 'l', 'i'),+ KBTS_SCRIPT_TAG_BAMUM = KBTS_FOURCC('b', 'a', 'm', 'u'),+ KBTS_SCRIPT_TAG_BASSA_VAH = KBTS_FOURCC('b', 'a', 's', 's'),+ KBTS_SCRIPT_TAG_BATAK = KBTS_FOURCC('b', 'a', 't', 'k'),+ KBTS_SCRIPT_TAG_BENGALI = KBTS_FOURCC('b', 'n', 'g', '2'),+ KBTS_SCRIPT_TAG_BHAIKSUKI = KBTS_FOURCC('b', 'h', 'k', 's'),+ KBTS_SCRIPT_TAG_BOPOMOFO = KBTS_FOURCC('b', 'o', 'p', 'o'),+ KBTS_SCRIPT_TAG_BRAHMI = KBTS_FOURCC('b', 'r', 'a', 'h'),+ KBTS_SCRIPT_TAG_BUGINESE = KBTS_FOURCC('b', 'u', 'g', 'i'),+ KBTS_SCRIPT_TAG_BUHID = KBTS_FOURCC('b', 'u', 'h', 'd'),+ KBTS_SCRIPT_TAG_CANADIAN_SYLLABICS = KBTS_FOURCC('c', 'a', 'n', 's'),+ KBTS_SCRIPT_TAG_CARIAN = KBTS_FOURCC('c', 'a', 'r', 'i'),+ KBTS_SCRIPT_TAG_CAUCASIAN_ALBANIAN = KBTS_FOURCC('a', 'g', 'h', 'b'),+ KBTS_SCRIPT_TAG_CHAKMA = KBTS_FOURCC('c', 'a', 'k', 'm'),+ KBTS_SCRIPT_TAG_CHAM = KBTS_FOURCC('c', 'h', 'a', 'm'),+ KBTS_SCRIPT_TAG_CHEROKEE = KBTS_FOURCC('c', 'h', 'e', 'r'),+ KBTS_SCRIPT_TAG_CHORASMIAN = KBTS_FOURCC('c', 'h', 'r', 's'),+ KBTS_SCRIPT_TAG_CJK_IDEOGRAPHIC = KBTS_FOURCC('h', 'a', 'n', 'i'),+ KBTS_SCRIPT_TAG_COPTIC = KBTS_FOURCC('c', 'o', 'p', 't'),+ KBTS_SCRIPT_TAG_CYPRIOT_SYLLABARY = KBTS_FOURCC('c', 'p', 'r', 't'),+ KBTS_SCRIPT_TAG_CYPRO_MINOAN = KBTS_FOURCC('c', 'p', 'm', 'n'),+ KBTS_SCRIPT_TAG_CYRILLIC = KBTS_FOURCC('c', 'y', 'r', 'l'),+ KBTS_SCRIPT_TAG_DEFAULT = KBTS_FOURCC('D', 'F', 'L', 'T'),+ KBTS_SCRIPT_TAG_DEFAULT2 = KBTS_FOURCC('D', 'F', 'L', 'T'),+ KBTS_SCRIPT_TAG_DESERET = KBTS_FOURCC('d', 's', 'r', 't'),+ KBTS_SCRIPT_TAG_DEVANAGARI = KBTS_FOURCC('d', 'e', 'v', '2'),+ KBTS_SCRIPT_TAG_DIVES_AKURU = KBTS_FOURCC('d', 'i', 'a', 'k'),+ KBTS_SCRIPT_TAG_DOGRA = KBTS_FOURCC('d', 'o', 'g', 'r'),+ KBTS_SCRIPT_TAG_DUPLOYAN = KBTS_FOURCC('d', 'u', 'p', 'l'),+ KBTS_SCRIPT_TAG_EGYPTIAN_HIEROGLYPHS = KBTS_FOURCC('e', 'g', 'y', 'p'),+ KBTS_SCRIPT_TAG_ELBASAN = KBTS_FOURCC('e', 'l', 'b', 'a'),+ KBTS_SCRIPT_TAG_ELYMAIC = KBTS_FOURCC('e', 'l', 'y', 'm'),+ KBTS_SCRIPT_TAG_ETHIOPIC = KBTS_FOURCC('e', 't', 'h', 'i'),+ KBTS_SCRIPT_TAG_GARAY = KBTS_FOURCC('g', 'a', 'r', 'a'),+ KBTS_SCRIPT_TAG_GEORGIAN = KBTS_FOURCC('g', 'e', 'o', 'r'),+ KBTS_SCRIPT_TAG_GLAGOLITIC = KBTS_FOURCC('g', 'l', 'a', 'g'),+ KBTS_SCRIPT_TAG_GOTHIC = KBTS_FOURCC('g', 'o', 't', 'h'),+ KBTS_SCRIPT_TAG_GRANTHA = KBTS_FOURCC('g', 'r', 'a', 'n'),+ KBTS_SCRIPT_TAG_GREEK = KBTS_FOURCC('g', 'r', 'e', 'k'),+ KBTS_SCRIPT_TAG_GUJARATI = KBTS_FOURCC('g', 'j', 'r', '2'),+ KBTS_SCRIPT_TAG_GUNJALA_GONDI = KBTS_FOURCC('g', 'o', 'n', 'g'),+ KBTS_SCRIPT_TAG_GURMUKHI = KBTS_FOURCC('g', 'u', 'r', '2'),+ KBTS_SCRIPT_TAG_GURUNG_KHEMA = KBTS_FOURCC('g', 'u', 'k', 'h'),+ KBTS_SCRIPT_TAG_HANGUL = KBTS_FOURCC('h', 'a', 'n', 'g'),+ KBTS_SCRIPT_TAG_HANIFI_ROHINGYA = KBTS_FOURCC('r', 'o', 'h', 'g'),+ KBTS_SCRIPT_TAG_HANUNOO = KBTS_FOURCC('h', 'a', 'n', 'o'),+ KBTS_SCRIPT_TAG_HATRAN = KBTS_FOURCC('h', 'a', 't', 'r'),+ KBTS_SCRIPT_TAG_HEBREW = KBTS_FOURCC('h', 'e', 'b', 'r'),+ KBTS_SCRIPT_TAG_HIRAGANA = KBTS_FOURCC('k', 'a', 'n', 'a'),+ KBTS_SCRIPT_TAG_IMPERIAL_ARAMAIC = KBTS_FOURCC('a', 'r', 'm', 'i'),+ KBTS_SCRIPT_TAG_INSCRIPTIONAL_PAHLAVI = KBTS_FOURCC('p', 'h', 'l', 'i'),+ KBTS_SCRIPT_TAG_INSCRIPTIONAL_PARTHIAN = KBTS_FOURCC('p', 'r', 't', 'i'),+ KBTS_SCRIPT_TAG_JAVANESE = KBTS_FOURCC('j', 'a', 'v', 'a'),+ KBTS_SCRIPT_TAG_KAITHI = KBTS_FOURCC('k', 't', 'h', 'i'),+ KBTS_SCRIPT_TAG_KANNADA = KBTS_FOURCC('k', 'n', 'd', '2'),+ KBTS_SCRIPT_TAG_KATAKANA = KBTS_FOURCC('k', 'a', 'n', 'a'),+ KBTS_SCRIPT_TAG_KAWI = KBTS_FOURCC('k', 'a', 'w', 'i'),+ KBTS_SCRIPT_TAG_KAYAH_LI = KBTS_FOURCC('k', 'a', 'l', 'i'),+ KBTS_SCRIPT_TAG_KHAROSHTHI = KBTS_FOURCC('k', 'h', 'a', 'r'),+ KBTS_SCRIPT_TAG_KHITAN_SMALL_SCRIPT = KBTS_FOURCC('k', 'i', 't', 's'),+ KBTS_SCRIPT_TAG_KHMER = KBTS_FOURCC('k', 'h', 'm', 'r'),+ KBTS_SCRIPT_TAG_KHOJKI = KBTS_FOURCC('k', 'h', 'o', 'j'),+ KBTS_SCRIPT_TAG_KHUDAWADI = KBTS_FOURCC('s', 'i', 'n', 'd'),+ KBTS_SCRIPT_TAG_KIRAT_RAI = KBTS_FOURCC('k', 'r', 'a', 'i'),+ KBTS_SCRIPT_TAG_LAO = KBTS_FOURCC('l', 'a', 'o', ' '),+ KBTS_SCRIPT_TAG_LATIN = KBTS_FOURCC('l', 'a', 't', 'n'),+ KBTS_SCRIPT_TAG_LEPCHA = KBTS_FOURCC('l', 'e', 'p', 'c'),+ KBTS_SCRIPT_TAG_LIMBU = KBTS_FOURCC('l', 'i', 'm', 'b'),+ KBTS_SCRIPT_TAG_LINEAR_A = KBTS_FOURCC('l', 'i', 'n', 'a'),+ KBTS_SCRIPT_TAG_LINEAR_B = KBTS_FOURCC('l', 'i', 'n', 'b'),+ KBTS_SCRIPT_TAG_LISU = KBTS_FOURCC('l', 'i', 's', 'u'),+ KBTS_SCRIPT_TAG_LYCIAN = KBTS_FOURCC('l', 'y', 'c', 'i'),+ KBTS_SCRIPT_TAG_LYDIAN = KBTS_FOURCC('l', 'y', 'd', 'i'),+ KBTS_SCRIPT_TAG_MAHAJANI = KBTS_FOURCC('m', 'a', 'h', 'j'),+ KBTS_SCRIPT_TAG_MAKASAR = KBTS_FOURCC('m', 'a', 'k', 'a'),+ KBTS_SCRIPT_TAG_MALAYALAM = KBTS_FOURCC('m', 'l', 'm', '2'),+ KBTS_SCRIPT_TAG_MANDAIC = KBTS_FOURCC('m', 'a', 'n', 'd'),+ KBTS_SCRIPT_TAG_MANICHAEAN = KBTS_FOURCC('m', 'a', 'n', 'i'),+ KBTS_SCRIPT_TAG_MARCHEN = KBTS_FOURCC('m', 'a', 'r', 'c'),+ KBTS_SCRIPT_TAG_MASARAM_GONDI = KBTS_FOURCC('g', 'o', 'n', 'm'),+ KBTS_SCRIPT_TAG_MEDEFAIDRIN = KBTS_FOURCC('m', 'e', 'd', 'f'),+ KBTS_SCRIPT_TAG_MEETEI_MAYEK = KBTS_FOURCC('m', 't', 'e', 'i'),+ KBTS_SCRIPT_TAG_MENDE_KIKAKUI = KBTS_FOURCC('m', 'e', 'n', 'd'),+ KBTS_SCRIPT_TAG_MEROITIC_CURSIVE = KBTS_FOURCC('m', 'e', 'r', 'c'),+ KBTS_SCRIPT_TAG_MEROITIC_HIEROGLYPHS = KBTS_FOURCC('m', 'e', 'r', 'o'),+ KBTS_SCRIPT_TAG_MIAO = KBTS_FOURCC('p', 'l', 'r', 'd'),+ KBTS_SCRIPT_TAG_MODI = KBTS_FOURCC('m', 'o', 'd', 'i'),+ KBTS_SCRIPT_TAG_MONGOLIAN = KBTS_FOURCC('m', 'o', 'n', 'g'),+ KBTS_SCRIPT_TAG_MRO = KBTS_FOURCC('m', 'r', 'o', 'o'),+ KBTS_SCRIPT_TAG_MULTANI = KBTS_FOURCC('m', 'u', 'l', 't'),+ KBTS_SCRIPT_TAG_MYANMAR = KBTS_FOURCC('m', 'y', 'm', '2'),+ KBTS_SCRIPT_TAG_NABATAEAN = KBTS_FOURCC('n', 'b', 'a', 't'),+ KBTS_SCRIPT_TAG_NAG_MUNDARI = KBTS_FOURCC('n', 'a', 'g', 'm'),+ KBTS_SCRIPT_TAG_NANDINAGARI = KBTS_FOURCC('n', 'a', 'n', 'd'),+ KBTS_SCRIPT_TAG_NEWA = KBTS_FOURCC('n', 'e', 'w', 'a'),+ KBTS_SCRIPT_TAG_NEW_TAI_LUE = KBTS_FOURCC('t', 'a', 'l', 'u'),+ KBTS_SCRIPT_TAG_NKO = KBTS_FOURCC('n', 'k', 'o', ' '),+ KBTS_SCRIPT_TAG_NUSHU = KBTS_FOURCC('n', 's', 'h', 'u'),+ KBTS_SCRIPT_TAG_NYIAKENG_PUACHUE_HMONG = KBTS_FOURCC('h', 'm', 'n', 'p'),+ KBTS_SCRIPT_TAG_OGHAM = KBTS_FOURCC('o', 'g', 'a', 'm'),+ KBTS_SCRIPT_TAG_OL_CHIKI = KBTS_FOURCC('o', 'l', 'c', 'k'),+ KBTS_SCRIPT_TAG_OL_ONAL = KBTS_FOURCC('o', 'n', 'a', 'o'),+ KBTS_SCRIPT_TAG_OLD_ITALIC = KBTS_FOURCC('i', 't', 'a', 'l'),+ KBTS_SCRIPT_TAG_OLD_HUNGARIAN = KBTS_FOURCC('h', 'u', 'n', 'g'),+ KBTS_SCRIPT_TAG_OLD_NORTH_ARABIAN = KBTS_FOURCC('n', 'a', 'r', 'b'),+ KBTS_SCRIPT_TAG_OLD_PERMIC = KBTS_FOURCC('p', 'e', 'r', 'm'),+ KBTS_SCRIPT_TAG_OLD_PERSIAN_CUNEIFORM = KBTS_FOURCC('x', 'p', 'e', 'o'),+ KBTS_SCRIPT_TAG_OLD_SOGDIAN = KBTS_FOURCC('s', 'o', 'g', 'o'),+ KBTS_SCRIPT_TAG_OLD_SOUTH_ARABIAN = KBTS_FOURCC('s', 'a', 'r', 'b'),+ KBTS_SCRIPT_TAG_OLD_TURKIC = KBTS_FOURCC('o', 'r', 'k', 'h'),+ KBTS_SCRIPT_TAG_OLD_UYGHUR = KBTS_FOURCC('o', 'u', 'g', 'r'),+ KBTS_SCRIPT_TAG_ODIA = KBTS_FOURCC('o', 'r', 'y', '2'),+ KBTS_SCRIPT_TAG_OSAGE = KBTS_FOURCC('o', 's', 'g', 'e'),+ KBTS_SCRIPT_TAG_OSMANYA = KBTS_FOURCC('o', 's', 'm', 'a'),+ KBTS_SCRIPT_TAG_PAHAWH_HMONG = KBTS_FOURCC('h', 'm', 'n', 'g'),+ KBTS_SCRIPT_TAG_PALMYRENE = KBTS_FOURCC('p', 'a', 'l', 'm'),+ KBTS_SCRIPT_TAG_PAU_CIN_HAU = KBTS_FOURCC('p', 'a', 'u', 'c'),+ KBTS_SCRIPT_TAG_PHAGS_PA = KBTS_FOURCC('p', 'h', 'a', 'g'),+ KBTS_SCRIPT_TAG_PHOENICIAN = KBTS_FOURCC('p', 'h', 'n', 'x'),+ KBTS_SCRIPT_TAG_PSALTER_PAHLAVI = KBTS_FOURCC('p', 'h', 'l', 'p'),+ KBTS_SCRIPT_TAG_REJANG = KBTS_FOURCC('r', 'j', 'n', 'g'),+ KBTS_SCRIPT_TAG_RUNIC = KBTS_FOURCC('r', 'u', 'n', 'r'),+ KBTS_SCRIPT_TAG_SAMARITAN = KBTS_FOURCC('s', 'a', 'm', 'r'),+ KBTS_SCRIPT_TAG_SAURASHTRA = KBTS_FOURCC('s', 'a', 'u', 'r'),+ KBTS_SCRIPT_TAG_SHARADA = KBTS_FOURCC('s', 'h', 'r', 'd'),+ KBTS_SCRIPT_TAG_SHAVIAN = KBTS_FOURCC('s', 'h', 'a', 'w'),+ KBTS_SCRIPT_TAG_SIDDHAM = KBTS_FOURCC('s', 'i', 'd', 'd'),+ KBTS_SCRIPT_TAG_SIGN_WRITING = KBTS_FOURCC('s', 'g', 'n', 'w'),+ KBTS_SCRIPT_TAG_SOGDIAN = KBTS_FOURCC('s', 'o', 'g', 'd'),+ KBTS_SCRIPT_TAG_SINHALA = KBTS_FOURCC('s', 'i', 'n', 'h'),+ KBTS_SCRIPT_TAG_SORA_SOMPENG = KBTS_FOURCC('s', 'o', 'r', 'a'),+ KBTS_SCRIPT_TAG_SOYOMBO = KBTS_FOURCC('s', 'o', 'y', 'o'),+ KBTS_SCRIPT_TAG_SUMERO_AKKADIAN_CUNEIFORM = KBTS_FOURCC('x', 's', 'u', 'x'),+ KBTS_SCRIPT_TAG_SUNDANESE = KBTS_FOURCC('s', 'u', 'n', 'd'),+ KBTS_SCRIPT_TAG_SUNUWAR = KBTS_FOURCC('s', 'u', 'n', 'u'),+ KBTS_SCRIPT_TAG_SYLOTI_NAGRI = KBTS_FOURCC('s', 'y', 'l', 'o'),+ KBTS_SCRIPT_TAG_SYRIAC = KBTS_FOURCC('s', 'y', 'r', 'c'),+ KBTS_SCRIPT_TAG_TAGALOG = KBTS_FOURCC('t', 'g', 'l', 'g'),+ KBTS_SCRIPT_TAG_TAGBANWA = KBTS_FOURCC('t', 'a', 'g', 'b'),+ KBTS_SCRIPT_TAG_TAI_LE = KBTS_FOURCC('t', 'a', 'l', 'e'),+ KBTS_SCRIPT_TAG_TAI_THAM = KBTS_FOURCC('l', 'a', 'n', 'a'),+ KBTS_SCRIPT_TAG_TAI_VIET = KBTS_FOURCC('t', 'a', 'v', 't'),+ KBTS_SCRIPT_TAG_TAKRI = KBTS_FOURCC('t', 'a', 'k', 'r'),+ KBTS_SCRIPT_TAG_TAMIL = KBTS_FOURCC('t', 'm', 'l', '2'),+ KBTS_SCRIPT_TAG_TANGSA = KBTS_FOURCC('t', 'n', 's', 'a'),+ KBTS_SCRIPT_TAG_TANGUT = KBTS_FOURCC('t', 'a', 'n', 'g'),+ KBTS_SCRIPT_TAG_TELUGU = KBTS_FOURCC('t', 'e', 'l', '2'),+ KBTS_SCRIPT_TAG_THAANA = KBTS_FOURCC('t', 'h', 'a', 'a'),+ KBTS_SCRIPT_TAG_THAI = KBTS_FOURCC('t', 'h', 'a', 'i'),+ KBTS_SCRIPT_TAG_TIBETAN = KBTS_FOURCC('t', 'i', 'b', 't'),+ KBTS_SCRIPT_TAG_TIFINAGH = KBTS_FOURCC('t', 'f', 'n', 'g'),+ KBTS_SCRIPT_TAG_TIRHUTA = KBTS_FOURCC('t', 'i', 'r', 'h'),+ KBTS_SCRIPT_TAG_TODHRI = KBTS_FOURCC('t', 'o', 'd', 'r'),+ KBTS_SCRIPT_TAG_TOTO = KBTS_FOURCC('t', 'o', 't', 'o'),+ KBTS_SCRIPT_TAG_TULU_TIGALARI = KBTS_FOURCC('t', 'u', 't', 'g'),+ KBTS_SCRIPT_TAG_UGARITIC_CUNEIFORM = KBTS_FOURCC('u', 'g', 'a', 'r'),+ KBTS_SCRIPT_TAG_VAI = KBTS_FOURCC('v', 'a', 'i', ' '),+ KBTS_SCRIPT_TAG_VITHKUQI = KBTS_FOURCC('v', 'i', 't', 'h'),+ KBTS_SCRIPT_TAG_WANCHO = KBTS_FOURCC('w', 'c', 'h', 'o'),+ KBTS_SCRIPT_TAG_WARANG_CITI = KBTS_FOURCC('w', 'a', 'r', 'a'),+ KBTS_SCRIPT_TAG_YEZIDI = KBTS_FOURCC('y', 'e', 'z', 'i'),+ KBTS_SCRIPT_TAG_YI = KBTS_FOURCC('y', 'i', ' ', ' '),+ KBTS_SCRIPT_TAG_ZANABAZAR_SQUARE = KBTS_FOURCC('z', 'a', 'n', 'b'),+};++typedef kbts_u32 kbts_script;+enum kbts_script_enum+{+ KBTS_SCRIPT_DONT_KNOW,+ KBTS_SCRIPT_ADLAM,+ KBTS_SCRIPT_AHOM,+ KBTS_SCRIPT_ANATOLIAN_HIEROGLYPHS,+ KBTS_SCRIPT_ARABIC,+ KBTS_SCRIPT_ARMENIAN,+ KBTS_SCRIPT_AVESTAN,+ KBTS_SCRIPT_BALINESE,+ KBTS_SCRIPT_BAMUM,+ KBTS_SCRIPT_BASSA_VAH,+ KBTS_SCRIPT_BATAK,+ KBTS_SCRIPT_BENGALI,+ KBTS_SCRIPT_BHAIKSUKI,+ KBTS_SCRIPT_BOPOMOFO,+ KBTS_SCRIPT_BRAHMI,+ KBTS_SCRIPT_BUGINESE,+ KBTS_SCRIPT_BUHID,+ KBTS_SCRIPT_CANADIAN_SYLLABICS,+ KBTS_SCRIPT_CARIAN,+ KBTS_SCRIPT_CAUCASIAN_ALBANIAN,+ KBTS_SCRIPT_CHAKMA,+ KBTS_SCRIPT_CHAM,+ KBTS_SCRIPT_CHEROKEE,+ KBTS_SCRIPT_CHORASMIAN,+ KBTS_SCRIPT_CJK_IDEOGRAPHIC,+ KBTS_SCRIPT_COPTIC,+ KBTS_SCRIPT_CYPRIOT_SYLLABARY,+ KBTS_SCRIPT_CYPRO_MINOAN,+ KBTS_SCRIPT_CYRILLIC,+ KBTS_SCRIPT_DEFAULT,+ KBTS_SCRIPT_DEFAULT2,+ KBTS_SCRIPT_DESERET,+ KBTS_SCRIPT_DEVANAGARI,+ KBTS_SCRIPT_DIVES_AKURU,+ KBTS_SCRIPT_DOGRA,+ KBTS_SCRIPT_DUPLOYAN,+ KBTS_SCRIPT_EGYPTIAN_HIEROGLYPHS,+ KBTS_SCRIPT_ELBASAN,+ KBTS_SCRIPT_ELYMAIC,+ KBTS_SCRIPT_ETHIOPIC,+ KBTS_SCRIPT_GARAY,+ KBTS_SCRIPT_GEORGIAN,+ KBTS_SCRIPT_GLAGOLITIC,+ KBTS_SCRIPT_GOTHIC,+ KBTS_SCRIPT_GRANTHA,+ KBTS_SCRIPT_GREEK,+ KBTS_SCRIPT_GUJARATI,+ KBTS_SCRIPT_GUNJALA_GONDI,+ KBTS_SCRIPT_GURMUKHI,+ KBTS_SCRIPT_GURUNG_KHEMA,+ KBTS_SCRIPT_HANGUL,+ KBTS_SCRIPT_HANIFI_ROHINGYA,+ KBTS_SCRIPT_HANUNOO,+ KBTS_SCRIPT_HATRAN,+ KBTS_SCRIPT_HEBREW,+ KBTS_SCRIPT_HIRAGANA,+ KBTS_SCRIPT_IMPERIAL_ARAMAIC,+ KBTS_SCRIPT_INSCRIPTIONAL_PAHLAVI,+ KBTS_SCRIPT_INSCRIPTIONAL_PARTHIAN,+ KBTS_SCRIPT_JAVANESE,+ KBTS_SCRIPT_KAITHI,+ KBTS_SCRIPT_KANNADA,+ KBTS_SCRIPT_KATAKANA,+ KBTS_SCRIPT_KAWI,+ KBTS_SCRIPT_KAYAH_LI,+ KBTS_SCRIPT_KHAROSHTHI,+ KBTS_SCRIPT_KHITAN_SMALL_SCRIPT,+ KBTS_SCRIPT_KHMER,+ KBTS_SCRIPT_KHOJKI,+ KBTS_SCRIPT_KHUDAWADI,+ KBTS_SCRIPT_KIRAT_RAI,+ KBTS_SCRIPT_LAO,+ KBTS_SCRIPT_LATIN,+ KBTS_SCRIPT_LEPCHA,+ KBTS_SCRIPT_LIMBU,+ KBTS_SCRIPT_LINEAR_A,+ KBTS_SCRIPT_LINEAR_B,+ KBTS_SCRIPT_LISU,+ KBTS_SCRIPT_LYCIAN,+ KBTS_SCRIPT_LYDIAN,+ KBTS_SCRIPT_MAHAJANI,+ KBTS_SCRIPT_MAKASAR,+ KBTS_SCRIPT_MALAYALAM,+ KBTS_SCRIPT_MANDAIC,+ KBTS_SCRIPT_MANICHAEAN,+ KBTS_SCRIPT_MARCHEN,+ KBTS_SCRIPT_MASARAM_GONDI,+ KBTS_SCRIPT_MEDEFAIDRIN,+ KBTS_SCRIPT_MEETEI_MAYEK,+ KBTS_SCRIPT_MENDE_KIKAKUI,+ KBTS_SCRIPT_MEROITIC_CURSIVE,+ KBTS_SCRIPT_MEROITIC_HIEROGLYPHS,+ KBTS_SCRIPT_MIAO,+ KBTS_SCRIPT_MODI,+ KBTS_SCRIPT_MONGOLIAN,+ KBTS_SCRIPT_MRO,+ KBTS_SCRIPT_MULTANI,+ KBTS_SCRIPT_MYANMAR,+ KBTS_SCRIPT_NABATAEAN,+ KBTS_SCRIPT_NAG_MUNDARI,+ KBTS_SCRIPT_NANDINAGARI,+ KBTS_SCRIPT_NEWA,+ KBTS_SCRIPT_NEW_TAI_LUE,+ KBTS_SCRIPT_NKO,+ KBTS_SCRIPT_NUSHU,+ KBTS_SCRIPT_NYIAKENG_PUACHUE_HMONG,+ KBTS_SCRIPT_OGHAM,+ KBTS_SCRIPT_OL_CHIKI,+ KBTS_SCRIPT_OL_ONAL,+ KBTS_SCRIPT_OLD_ITALIC,+ KBTS_SCRIPT_OLD_HUNGARIAN,+ KBTS_SCRIPT_OLD_NORTH_ARABIAN,+ KBTS_SCRIPT_OLD_PERMIC,+ KBTS_SCRIPT_OLD_PERSIAN_CUNEIFORM,+ KBTS_SCRIPT_OLD_SOGDIAN,+ KBTS_SCRIPT_OLD_SOUTH_ARABIAN,+ KBTS_SCRIPT_OLD_TURKIC,+ KBTS_SCRIPT_OLD_UYGHUR,+ KBTS_SCRIPT_ODIA,+ KBTS_SCRIPT_OSAGE,+ KBTS_SCRIPT_OSMANYA,+ KBTS_SCRIPT_PAHAWH_HMONG,+ KBTS_SCRIPT_PALMYRENE,+ KBTS_SCRIPT_PAU_CIN_HAU,+ KBTS_SCRIPT_PHAGS_PA,+ KBTS_SCRIPT_PHOENICIAN,+ KBTS_SCRIPT_PSALTER_PAHLAVI,+ KBTS_SCRIPT_REJANG,+ KBTS_SCRIPT_RUNIC,+ KBTS_SCRIPT_SAMARITAN,+ KBTS_SCRIPT_SAURASHTRA,+ KBTS_SCRIPT_SHARADA,+ KBTS_SCRIPT_SHAVIAN,+ KBTS_SCRIPT_SIDDHAM,+ KBTS_SCRIPT_SIGN_WRITING,+ KBTS_SCRIPT_SOGDIAN,+ KBTS_SCRIPT_SINHALA,+ KBTS_SCRIPT_SORA_SOMPENG,+ KBTS_SCRIPT_SOYOMBO,+ KBTS_SCRIPT_SUMERO_AKKADIAN_CUNEIFORM,+ KBTS_SCRIPT_SUNDANESE,+ KBTS_SCRIPT_SUNUWAR,+ KBTS_SCRIPT_SYLOTI_NAGRI,+ KBTS_SCRIPT_SYRIAC,+ KBTS_SCRIPT_TAGALOG,+ KBTS_SCRIPT_TAGBANWA,+ KBTS_SCRIPT_TAI_LE,+ KBTS_SCRIPT_TAI_THAM,+ KBTS_SCRIPT_TAI_VIET,+ KBTS_SCRIPT_TAKRI,+ KBTS_SCRIPT_TAMIL,+ KBTS_SCRIPT_TANGSA,+ KBTS_SCRIPT_TANGUT,+ KBTS_SCRIPT_TELUGU,+ KBTS_SCRIPT_THAANA,+ KBTS_SCRIPT_THAI,+ KBTS_SCRIPT_TIBETAN,+ KBTS_SCRIPT_TIFINAGH,+ KBTS_SCRIPT_TIRHUTA,+ KBTS_SCRIPT_TODHRI,+ KBTS_SCRIPT_TOTO,+ KBTS_SCRIPT_TULU_TIGALARI,+ KBTS_SCRIPT_UGARITIC_CUNEIFORM,+ KBTS_SCRIPT_VAI,+ KBTS_SCRIPT_VITHKUQI,+ KBTS_SCRIPT_WANCHO,+ KBTS_SCRIPT_WARANG_CITI,+ KBTS_SCRIPT_YEZIDI,+ KBTS_SCRIPT_YI,+ KBTS_SCRIPT_ZANABAZAR_SQUARE,+ KBTS_SCRIPT_COUNT,+};++typedef kbts_u32 kbts_feature_tag;+enum kbts_feature_tag_enum+{+ KBTS_FEATURE_TAG_UNREGISTERED = KBTS_FOURCC(0, 0, 0, 0), // Features that aren't pre-defined in the OpenType spec+ KBTS_FEATURE_TAG_isol = KBTS_FOURCC('i', 's', 'o', 'l'), // Isolated Forms+ KBTS_FEATURE_TAG_fina = KBTS_FOURCC('f', 'i', 'n', 'a'), // Terminal Forms+ KBTS_FEATURE_TAG_fin2 = KBTS_FOURCC('f', 'i', 'n', '2'), // Terminal Forms #2+ KBTS_FEATURE_TAG_fin3 = KBTS_FOURCC('f', 'i', 'n', '3'), // Terminal Forms #3+ KBTS_FEATURE_TAG_medi = KBTS_FOURCC('m', 'e', 'd', 'i'), // Medial Forms+ KBTS_FEATURE_TAG_med2 = KBTS_FOURCC('m', 'e', 'd', '2'), // Medial Forms #2+ KBTS_FEATURE_TAG_init = KBTS_FOURCC('i', 'n', 'i', 't'), // Initial Forms+ KBTS_FEATURE_TAG_ljmo = KBTS_FOURCC('l', 'j', 'm', 'o'), // Leading Jamo Forms+ KBTS_FEATURE_TAG_vjmo = KBTS_FOURCC('v', 'j', 'm', 'o'), // Vowel Jamo Forms+ KBTS_FEATURE_TAG_tjmo = KBTS_FOURCC('t', 'j', 'm', 'o'), // Trailing Jamo Forms+ KBTS_FEATURE_TAG_rphf = KBTS_FOURCC('r', 'p', 'h', 'f'), // Reph Form+ KBTS_FEATURE_TAG_blwf = KBTS_FOURCC('b', 'l', 'w', 'f'), // Below-base Forms+ KBTS_FEATURE_TAG_half = KBTS_FOURCC('h', 'a', 'l', 'f'), // Half Forms+ KBTS_FEATURE_TAG_pstf = KBTS_FOURCC('p', 's', 't', 'f'), // Post-base Forms+ KBTS_FEATURE_TAG_abvf = KBTS_FOURCC('a', 'b', 'v', 'f'), // Above-base Forms+ KBTS_FEATURE_TAG_pref = KBTS_FOURCC('p', 'r', 'e', 'f'), // Pre-base Forms+ KBTS_FEATURE_TAG_numr = KBTS_FOURCC('n', 'u', 'm', 'r'), // Numerators+ KBTS_FEATURE_TAG_frac = KBTS_FOURCC('f', 'r', 'a', 'c'), // Fractions+ KBTS_FEATURE_TAG_dnom = KBTS_FOURCC('d', 'n', 'o', 'm'), // Denominators+ KBTS_FEATURE_TAG_cfar = KBTS_FOURCC('c', 'f', 'a', 'r'), // Conjunct Form After Ro+ KBTS_FEATURE_TAG_aalt = KBTS_FOURCC('a', 'a', 'l', 't'), // Access All Alternates+ KBTS_FEATURE_TAG_abvm = KBTS_FOURCC('a', 'b', 'v', 'm'), // Above-base Mark Positioning+ KBTS_FEATURE_TAG_abvs = KBTS_FOURCC('a', 'b', 'v', 's'), // Above-base Substitutions+ KBTS_FEATURE_TAG_afrc = KBTS_FOURCC('a', 'f', 'r', 'c'), // Alternative Fractions+ KBTS_FEATURE_TAG_akhn = KBTS_FOURCC('a', 'k', 'h', 'n'), // Akhand+ KBTS_FEATURE_TAG_apkn = KBTS_FOURCC('a', 'p', 'k', 'n'), // Kerning for Alternate Proportional Widths+ KBTS_FEATURE_TAG_blwm = KBTS_FOURCC('b', 'l', 'w', 'm'), // Below-base Mark Positioning+ KBTS_FEATURE_TAG_blws = KBTS_FOURCC('b', 'l', 'w', 's'), // Below-base Substitutions+ KBTS_FEATURE_TAG_calt = KBTS_FOURCC('c', 'a', 'l', 't'), // Contextual Alternates+ KBTS_FEATURE_TAG_case = KBTS_FOURCC('c', 'a', 's', 'e'), // Case-sensitive Forms+ KBTS_FEATURE_TAG_ccmp = KBTS_FOURCC('c', 'c', 'm', 'p'), // Glyph Composition / Decomposition+ KBTS_FEATURE_TAG_chws = KBTS_FOURCC('c', 'h', 'w', 's'), // Contextual Half-width Spacing+ KBTS_FEATURE_TAG_cjct = KBTS_FOURCC('c', 'j', 'c', 't'), // Conjunct Forms+ KBTS_FEATURE_TAG_clig = KBTS_FOURCC('c', 'l', 'i', 'g'), // Contextual Ligatures+ KBTS_FEATURE_TAG_cpct = KBTS_FOURCC('c', 'p', 'c', 't'), // Centered CJK Punctuation+ KBTS_FEATURE_TAG_cpsp = KBTS_FOURCC('c', 'p', 's', 'p'), // Capital Spacing+ KBTS_FEATURE_TAG_cswh = KBTS_FOURCC('c', 's', 'w', 'h'), // Contextual Swash+ KBTS_FEATURE_TAG_curs = KBTS_FOURCC('c', 'u', 'r', 's'), // Cursive Positioning+ KBTS_FEATURE_TAG_cv01 = KBTS_FOURCC('c', 'v', '0', '1'), // Character Variant 1+ KBTS_FEATURE_TAG_cv02 = KBTS_FOURCC('c', 'v', '0', '2'), // Character Variant 2+ KBTS_FEATURE_TAG_cv03 = KBTS_FOURCC('c', 'v', '0', '3'), // Character Variant 3+ KBTS_FEATURE_TAG_cv04 = KBTS_FOURCC('c', 'v', '0', '4'), // Character Variant 4+ KBTS_FEATURE_TAG_cv05 = KBTS_FOURCC('c', 'v', '0', '5'), // Character Variant 5+ KBTS_FEATURE_TAG_cv06 = KBTS_FOURCC('c', 'v', '0', '6'), // Character Variant 6+ KBTS_FEATURE_TAG_cv07 = KBTS_FOURCC('c', 'v', '0', '7'), // Character Variant 7+ KBTS_FEATURE_TAG_cv08 = KBTS_FOURCC('c', 'v', '0', '8'), // Character Variant 8+ KBTS_FEATURE_TAG_cv09 = KBTS_FOURCC('c', 'v', '0', '9'), // Character Variant 9+ KBTS_FEATURE_TAG_cv10 = KBTS_FOURCC('c', 'v', '1', '0'), // Character Variant 10+ KBTS_FEATURE_TAG_cv11 = KBTS_FOURCC('c', 'v', '1', '1'), // Character Variant 11+ KBTS_FEATURE_TAG_cv12 = KBTS_FOURCC('c', 'v', '1', '2'), // Character Variant 12+ KBTS_FEATURE_TAG_cv13 = KBTS_FOURCC('c', 'v', '1', '3'), // Character Variant 13+ KBTS_FEATURE_TAG_cv14 = KBTS_FOURCC('c', 'v', '1', '4'), // Character Variant 14+ KBTS_FEATURE_TAG_cv15 = KBTS_FOURCC('c', 'v', '1', '5'), // Character Variant 15+ KBTS_FEATURE_TAG_cv16 = KBTS_FOURCC('c', 'v', '1', '6'), // Character Variant 16+ KBTS_FEATURE_TAG_cv17 = KBTS_FOURCC('c', 'v', '1', '7'), // Character Variant 17+ KBTS_FEATURE_TAG_cv18 = KBTS_FOURCC('c', 'v', '1', '8'), // Character Variant 18+ KBTS_FEATURE_TAG_cv19 = KBTS_FOURCC('c', 'v', '1', '9'), // Character Variant 19+ KBTS_FEATURE_TAG_cv20 = KBTS_FOURCC('c', 'v', '2', '0'), // Character Variant 20+ KBTS_FEATURE_TAG_cv21 = KBTS_FOURCC('c', 'v', '2', '1'), // Character Variant 21+ KBTS_FEATURE_TAG_cv22 = KBTS_FOURCC('c', 'v', '2', '2'), // Character Variant 22+ KBTS_FEATURE_TAG_cv23 = KBTS_FOURCC('c', 'v', '2', '3'), // Character Variant 23+ KBTS_FEATURE_TAG_cv24 = KBTS_FOURCC('c', 'v', '2', '4'), // Character Variant 24+ KBTS_FEATURE_TAG_cv25 = KBTS_FOURCC('c', 'v', '2', '5'), // Character Variant 25+ KBTS_FEATURE_TAG_cv26 = KBTS_FOURCC('c', 'v', '2', '6'), // Character Variant 26+ KBTS_FEATURE_TAG_cv27 = KBTS_FOURCC('c', 'v', '2', '7'), // Character Variant 27+ KBTS_FEATURE_TAG_cv28 = KBTS_FOURCC('c', 'v', '2', '8'), // Character Variant 28+ KBTS_FEATURE_TAG_cv29 = KBTS_FOURCC('c', 'v', '2', '9'), // Character Variant 29+ KBTS_FEATURE_TAG_cv30 = KBTS_FOURCC('c', 'v', '3', '0'), // Character Variant 30+ KBTS_FEATURE_TAG_cv31 = KBTS_FOURCC('c', 'v', '3', '1'), // Character Variant 31+ KBTS_FEATURE_TAG_cv32 = KBTS_FOURCC('c', 'v', '3', '2'), // Character Variant 32+ KBTS_FEATURE_TAG_cv33 = KBTS_FOURCC('c', 'v', '3', '3'), // Character Variant 33+ KBTS_FEATURE_TAG_cv34 = KBTS_FOURCC('c', 'v', '3', '4'), // Character Variant 34+ KBTS_FEATURE_TAG_cv35 = KBTS_FOURCC('c', 'v', '3', '5'), // Character Variant 35+ KBTS_FEATURE_TAG_cv36 = KBTS_FOURCC('c', 'v', '3', '6'), // Character Variant 36+ KBTS_FEATURE_TAG_cv37 = KBTS_FOURCC('c', 'v', '3', '7'), // Character Variant 37+ KBTS_FEATURE_TAG_cv38 = KBTS_FOURCC('c', 'v', '3', '8'), // Character Variant 38+ KBTS_FEATURE_TAG_cv39 = KBTS_FOURCC('c', 'v', '3', '9'), // Character Variant 39+ KBTS_FEATURE_TAG_cv40 = KBTS_FOURCC('c', 'v', '4', '0'), // Character Variant 40+ KBTS_FEATURE_TAG_cv41 = KBTS_FOURCC('c', 'v', '4', '1'), // Character Variant 41+ KBTS_FEATURE_TAG_cv42 = KBTS_FOURCC('c', 'v', '4', '2'), // Character Variant 42+ KBTS_FEATURE_TAG_cv43 = KBTS_FOURCC('c', 'v', '4', '3'), // Character Variant 43+ KBTS_FEATURE_TAG_cv44 = KBTS_FOURCC('c', 'v', '4', '4'), // Character Variant 44+ KBTS_FEATURE_TAG_cv45 = KBTS_FOURCC('c', 'v', '4', '5'), // Character Variant 45+ KBTS_FEATURE_TAG_cv46 = KBTS_FOURCC('c', 'v', '4', '6'), // Character Variant 46+ KBTS_FEATURE_TAG_cv47 = KBTS_FOURCC('c', 'v', '4', '7'), // Character Variant 47+ KBTS_FEATURE_TAG_cv48 = KBTS_FOURCC('c', 'v', '4', '8'), // Character Variant 48+ KBTS_FEATURE_TAG_cv49 = KBTS_FOURCC('c', 'v', '4', '9'), // Character Variant 49+ KBTS_FEATURE_TAG_cv50 = KBTS_FOURCC('c', 'v', '5', '0'), // Character Variant 50+ KBTS_FEATURE_TAG_cv51 = KBTS_FOURCC('c', 'v', '5', '1'), // Character Variant 51+ KBTS_FEATURE_TAG_cv52 = KBTS_FOURCC('c', 'v', '5', '2'), // Character Variant 52+ KBTS_FEATURE_TAG_cv53 = KBTS_FOURCC('c', 'v', '5', '3'), // Character Variant 53+ KBTS_FEATURE_TAG_cv54 = KBTS_FOURCC('c', 'v', '5', '4'), // Character Variant 54+ KBTS_FEATURE_TAG_cv55 = KBTS_FOURCC('c', 'v', '5', '5'), // Character Variant 55+ KBTS_FEATURE_TAG_cv56 = KBTS_FOURCC('c', 'v', '5', '6'), // Character Variant 56+ KBTS_FEATURE_TAG_cv57 = KBTS_FOURCC('c', 'v', '5', '7'), // Character Variant 57+ KBTS_FEATURE_TAG_cv58 = KBTS_FOURCC('c', 'v', '5', '8'), // Character Variant 58+ KBTS_FEATURE_TAG_cv59 = KBTS_FOURCC('c', 'v', '5', '9'), // Character Variant 59+ KBTS_FEATURE_TAG_cv60 = KBTS_FOURCC('c', 'v', '6', '0'), // Character Variant 60+ KBTS_FEATURE_TAG_cv61 = KBTS_FOURCC('c', 'v', '6', '1'), // Character Variant 61+ KBTS_FEATURE_TAG_cv62 = KBTS_FOURCC('c', 'v', '6', '2'), // Character Variant 62+ KBTS_FEATURE_TAG_cv63 = KBTS_FOURCC('c', 'v', '6', '3'), // Character Variant 63+ KBTS_FEATURE_TAG_cv64 = KBTS_FOURCC('c', 'v', '6', '4'), // Character Variant 64+ KBTS_FEATURE_TAG_cv65 = KBTS_FOURCC('c', 'v', '6', '5'), // Character Variant 65+ KBTS_FEATURE_TAG_cv66 = KBTS_FOURCC('c', 'v', '6', '6'), // Character Variant 66+ KBTS_FEATURE_TAG_cv67 = KBTS_FOURCC('c', 'v', '6', '7'), // Character Variant 67+ KBTS_FEATURE_TAG_cv68 = KBTS_FOURCC('c', 'v', '6', '8'), // Character Variant 68+ KBTS_FEATURE_TAG_cv69 = KBTS_FOURCC('c', 'v', '6', '9'), // Character Variant 69+ KBTS_FEATURE_TAG_cv70 = KBTS_FOURCC('c', 'v', '7', '0'), // Character Variant 70+ KBTS_FEATURE_TAG_cv71 = KBTS_FOURCC('c', 'v', '7', '1'), // Character Variant 71+ KBTS_FEATURE_TAG_cv72 = KBTS_FOURCC('c', 'v', '7', '2'), // Character Variant 72+ KBTS_FEATURE_TAG_cv73 = KBTS_FOURCC('c', 'v', '7', '3'), // Character Variant 73+ KBTS_FEATURE_TAG_cv74 = KBTS_FOURCC('c', 'v', '7', '4'), // Character Variant 74+ KBTS_FEATURE_TAG_cv75 = KBTS_FOURCC('c', 'v', '7', '5'), // Character Variant 75+ KBTS_FEATURE_TAG_cv76 = KBTS_FOURCC('c', 'v', '7', '6'), // Character Variant 76+ KBTS_FEATURE_TAG_cv77 = KBTS_FOURCC('c', 'v', '7', '7'), // Character Variant 77+ KBTS_FEATURE_TAG_cv78 = KBTS_FOURCC('c', 'v', '7', '8'), // Character Variant 78+ KBTS_FEATURE_TAG_cv79 = KBTS_FOURCC('c', 'v', '7', '9'), // Character Variant 79+ KBTS_FEATURE_TAG_cv80 = KBTS_FOURCC('c', 'v', '8', '0'), // Character Variant 80+ KBTS_FEATURE_TAG_cv81 = KBTS_FOURCC('c', 'v', '8', '1'), // Character Variant 81+ KBTS_FEATURE_TAG_cv82 = KBTS_FOURCC('c', 'v', '8', '2'), // Character Variant 82+ KBTS_FEATURE_TAG_cv83 = KBTS_FOURCC('c', 'v', '8', '3'), // Character Variant 83+ KBTS_FEATURE_TAG_cv84 = KBTS_FOURCC('c', 'v', '8', '4'), // Character Variant 84+ KBTS_FEATURE_TAG_cv85 = KBTS_FOURCC('c', 'v', '8', '5'), // Character Variant 85+ KBTS_FEATURE_TAG_cv86 = KBTS_FOURCC('c', 'v', '8', '6'), // Character Variant 86+ KBTS_FEATURE_TAG_cv87 = KBTS_FOURCC('c', 'v', '8', '7'), // Character Variant 87+ KBTS_FEATURE_TAG_cv88 = KBTS_FOURCC('c', 'v', '8', '8'), // Character Variant 88+ KBTS_FEATURE_TAG_cv89 = KBTS_FOURCC('c', 'v', '8', '9'), // Character Variant 89+ KBTS_FEATURE_TAG_cv90 = KBTS_FOURCC('c', 'v', '9', '0'), // Character Variant 90+ KBTS_FEATURE_TAG_cv91 = KBTS_FOURCC('c', 'v', '9', '1'), // Character Variant 91+ KBTS_FEATURE_TAG_cv92 = KBTS_FOURCC('c', 'v', '9', '2'), // Character Variant 92+ KBTS_FEATURE_TAG_cv93 = KBTS_FOURCC('c', 'v', '9', '3'), // Character Variant 93+ KBTS_FEATURE_TAG_cv94 = KBTS_FOURCC('c', 'v', '9', '4'), // Character Variant 94+ KBTS_FEATURE_TAG_cv95 = KBTS_FOURCC('c', 'v', '9', '5'), // Character Variant 95+ KBTS_FEATURE_TAG_cv96 = KBTS_FOURCC('c', 'v', '9', '6'), // Character Variant 96+ KBTS_FEATURE_TAG_cv97 = KBTS_FOURCC('c', 'v', '9', '7'), // Character Variant 97+ KBTS_FEATURE_TAG_cv98 = KBTS_FOURCC('c', 'v', '9', '8'), // Character Variant 98+ KBTS_FEATURE_TAG_cv99 = KBTS_FOURCC('c', 'v', '9', '9'), // Character Variant 99+ KBTS_FEATURE_TAG_c2pc = KBTS_FOURCC('c', '2', 'p', 'c'), // Petite Capitals From Capitals+ KBTS_FEATURE_TAG_c2sc = KBTS_FOURCC('c', '2', 's', 'c'), // Small Capitals From Capitals+ KBTS_FEATURE_TAG_dist = KBTS_FOURCC('d', 'i', 's', 't'), // Distances+ KBTS_FEATURE_TAG_dlig = KBTS_FOURCC('d', 'l', 'i', 'g'), // Discretionary Ligatures+ KBTS_FEATURE_TAG_dtls = KBTS_FOURCC('d', 't', 'l', 's'), // Dotless Forms+ KBTS_FEATURE_TAG_expt = KBTS_FOURCC('e', 'x', 'p', 't'), // Expert Forms+ KBTS_FEATURE_TAG_falt = KBTS_FOURCC('f', 'a', 'l', 't'), // Final Glyph on Line Alternates+ KBTS_FEATURE_TAG_flac = KBTS_FOURCC('f', 'l', 'a', 'c'), // Flattened Accent Forms+ KBTS_FEATURE_TAG_fwid = KBTS_FOURCC('f', 'w', 'i', 'd'), // Full Widths+ KBTS_FEATURE_TAG_haln = KBTS_FOURCC('h', 'a', 'l', 'n'), // Halant Forms+ KBTS_FEATURE_TAG_halt = KBTS_FOURCC('h', 'a', 'l', 't'), // Alternate Half Widths+ KBTS_FEATURE_TAG_hist = KBTS_FOURCC('h', 'i', 's', 't'), // Historical Forms+ KBTS_FEATURE_TAG_hkna = KBTS_FOURCC('h', 'k', 'n', 'a'), // Horizontal Kana Alternates+ KBTS_FEATURE_TAG_hlig = KBTS_FOURCC('h', 'l', 'i', 'g'), // Historical Ligatures+ KBTS_FEATURE_TAG_hngl = KBTS_FOURCC('h', 'n', 'g', 'l'), // Hangul+ KBTS_FEATURE_TAG_hojo = KBTS_FOURCC('h', 'o', 'j', 'o'), // Hojo Kanji Forms (JIS X 0212-1990 Kanji Forms)+ KBTS_FEATURE_TAG_hwid = KBTS_FOURCC('h', 'w', 'i', 'd'), // Half Widths+ KBTS_FEATURE_TAG_ital = KBTS_FOURCC('i', 't', 'a', 'l'), // Italics+ KBTS_FEATURE_TAG_jalt = KBTS_FOURCC('j', 'a', 'l', 't'), // Justification Alternates+ KBTS_FEATURE_TAG_jp78 = KBTS_FOURCC('j', 'p', '7', '8'), // JIS78 Forms+ KBTS_FEATURE_TAG_jp83 = KBTS_FOURCC('j', 'p', '8', '3'), // JIS83 Forms+ KBTS_FEATURE_TAG_jp90 = KBTS_FOURCC('j', 'p', '9', '0'), // JIS90 Forms+ KBTS_FEATURE_TAG_jp04 = KBTS_FOURCC('j', 'p', '0', '4'), // JIS2004 Forms+ KBTS_FEATURE_TAG_kern = KBTS_FOURCC('k', 'e', 'r', 'n'), // Kerning+ KBTS_FEATURE_TAG_lfbd = KBTS_FOURCC('l', 'f', 'b', 'd'), // Left Bounds+ KBTS_FEATURE_TAG_liga = KBTS_FOURCC('l', 'i', 'g', 'a'), // Standard Ligatures+ KBTS_FEATURE_TAG_lnum = KBTS_FOURCC('l', 'n', 'u', 'm'), // Lining Figures+ KBTS_FEATURE_TAG_locl = KBTS_FOURCC('l', 'o', 'c', 'l'), // Localized Forms+ KBTS_FEATURE_TAG_ltra = KBTS_FOURCC('l', 't', 'r', 'a'), // Left-to-right Alternates+ KBTS_FEATURE_TAG_ltrm = KBTS_FOURCC('l', 't', 'r', 'm'), // Left-to-right Mirrored Forms+ KBTS_FEATURE_TAG_mark = KBTS_FOURCC('m', 'a', 'r', 'k'), // Mark Positioning+ KBTS_FEATURE_TAG_mgrk = KBTS_FOURCC('m', 'g', 'r', 'k'), // Mathematical Greek+ KBTS_FEATURE_TAG_mkmk = KBTS_FOURCC('m', 'k', 'm', 'k'), // Mark to Mark Positioning+ KBTS_FEATURE_TAG_mset = KBTS_FOURCC('m', 's', 'e', 't'), // Mark Positioning via Substitution+ KBTS_FEATURE_TAG_nalt = KBTS_FOURCC('n', 'a', 'l', 't'), // Alternate Annotation Forms+ KBTS_FEATURE_TAG_nlck = KBTS_FOURCC('n', 'l', 'c', 'k'), // NLC Kanji Forms+ KBTS_FEATURE_TAG_nukt = KBTS_FOURCC('n', 'u', 'k', 't'), // Nukta Forms+ KBTS_FEATURE_TAG_onum = KBTS_FOURCC('o', 'n', 'u', 'm'), // Oldstyle Figures+ KBTS_FEATURE_TAG_opbd = KBTS_FOURCC('o', 'p', 'b', 'd'), // Optical Bounds+ KBTS_FEATURE_TAG_ordn = KBTS_FOURCC('o', 'r', 'd', 'n'), // Ordinals+ KBTS_FEATURE_TAG_ornm = KBTS_FOURCC('o', 'r', 'n', 'm'), // Ornaments+ KBTS_FEATURE_TAG_palt = KBTS_FOURCC('p', 'a', 'l', 't'), // Proportional Alternate Widths+ KBTS_FEATURE_TAG_pcap = KBTS_FOURCC('p', 'c', 'a', 'p'), // Petite Capitals+ KBTS_FEATURE_TAG_pkna = KBTS_FOURCC('p', 'k', 'n', 'a'), // Proportional Kana+ KBTS_FEATURE_TAG_pnum = KBTS_FOURCC('p', 'n', 'u', 'm'), // Proportional Figures+ KBTS_FEATURE_TAG_pres = KBTS_FOURCC('p', 'r', 'e', 's'), // Pre-base Substitutions+ KBTS_FEATURE_TAG_psts = KBTS_FOURCC('p', 's', 't', 's'), // Post-base Substitutions+ KBTS_FEATURE_TAG_pwid = KBTS_FOURCC('p', 'w', 'i', 'd'), // Proportional Widths+ KBTS_FEATURE_TAG_qwid = KBTS_FOURCC('q', 'w', 'i', 'd'), // Quarter Widths+ KBTS_FEATURE_TAG_rand = KBTS_FOURCC('r', 'a', 'n', 'd'), // Randomize+ KBTS_FEATURE_TAG_rclt = KBTS_FOURCC('r', 'c', 'l', 't'), // Required Contextual Alternates+ KBTS_FEATURE_TAG_rkrf = KBTS_FOURCC('r', 'k', 'r', 'f'), // Rakar Forms+ KBTS_FEATURE_TAG_rlig = KBTS_FOURCC('r', 'l', 'i', 'g'), // Required Ligatures+ KBTS_FEATURE_TAG_rtbd = KBTS_FOURCC('r', 't', 'b', 'd'), // Right Bounds+ KBTS_FEATURE_TAG_rtla = KBTS_FOURCC('r', 't', 'l', 'a'), // Right-to-left Alternates+ KBTS_FEATURE_TAG_rtlm = KBTS_FOURCC('r', 't', 'l', 'm'), // Right-to-left Mirrored Forms+ KBTS_FEATURE_TAG_ruby = KBTS_FOURCC('r', 'u', 'b', 'y'), // Ruby Notation Forms+ KBTS_FEATURE_TAG_rvrn = KBTS_FOURCC('r', 'v', 'r', 'n'), // Required Variation Alternates+ KBTS_FEATURE_TAG_salt = KBTS_FOURCC('s', 'a', 'l', 't'), // Stylistic Alternates+ KBTS_FEATURE_TAG_sinf = KBTS_FOURCC('s', 'i', 'n', 'f'), // Scientific Inferiors+ KBTS_FEATURE_TAG_size = KBTS_FOURCC('s', 'i', 'z', 'e'), // Optical size+ KBTS_FEATURE_TAG_smcp = KBTS_FOURCC('s', 'm', 'c', 'p'), // Small Capitals+ KBTS_FEATURE_TAG_smpl = KBTS_FOURCC('s', 'm', 'p', 'l'), // Simplified Forms+ KBTS_FEATURE_TAG_ss01 = KBTS_FOURCC('s', 's', '0', '1'), // Stylistic Set 1+ KBTS_FEATURE_TAG_ss02 = KBTS_FOURCC('s', 's', '0', '2'), // Stylistic Set 2+ KBTS_FEATURE_TAG_ss03 = KBTS_FOURCC('s', 's', '0', '3'), // Stylistic Set 3+ KBTS_FEATURE_TAG_ss04 = KBTS_FOURCC('s', 's', '0', '4'), // Stylistic Set 4+ KBTS_FEATURE_TAG_ss05 = KBTS_FOURCC('s', 's', '0', '5'), // Stylistic Set 5+ KBTS_FEATURE_TAG_ss06 = KBTS_FOURCC('s', 's', '0', '6'), // Stylistic Set 6+ KBTS_FEATURE_TAG_ss07 = KBTS_FOURCC('s', 's', '0', '7'), // Stylistic Set 7+ KBTS_FEATURE_TAG_ss08 = KBTS_FOURCC('s', 's', '0', '8'), // Stylistic Set 8+ KBTS_FEATURE_TAG_ss09 = KBTS_FOURCC('s', 's', '0', '9'), // Stylistic Set 9+ KBTS_FEATURE_TAG_ss10 = KBTS_FOURCC('s', 's', '1', '0'), // Stylistic Set 10+ KBTS_FEATURE_TAG_ss11 = KBTS_FOURCC('s', 's', '1', '1'), // Stylistic Set 11+ KBTS_FEATURE_TAG_ss12 = KBTS_FOURCC('s', 's', '1', '2'), // Stylistic Set 12+ KBTS_FEATURE_TAG_ss13 = KBTS_FOURCC('s', 's', '1', '3'), // Stylistic Set 13+ KBTS_FEATURE_TAG_ss14 = KBTS_FOURCC('s', 's', '1', '4'), // Stylistic Set 14+ KBTS_FEATURE_TAG_ss15 = KBTS_FOURCC('s', 's', '1', '5'), // Stylistic Set 15+ KBTS_FEATURE_TAG_ss16 = KBTS_FOURCC('s', 's', '1', '6'), // Stylistic Set 16+ KBTS_FEATURE_TAG_ss17 = KBTS_FOURCC('s', 's', '1', '7'), // Stylistic Set 17+ KBTS_FEATURE_TAG_ss18 = KBTS_FOURCC('s', 's', '1', '8'), // Stylistic Set 18+ KBTS_FEATURE_TAG_ss19 = KBTS_FOURCC('s', 's', '1', '9'), // Stylistic Set 19+ KBTS_FEATURE_TAG_ss20 = KBTS_FOURCC('s', 's', '2', '0'), // Stylistic Set 20+ KBTS_FEATURE_TAG_ssty = KBTS_FOURCC('s', 's', 't', 'y'), // Math Script-style Alternates+ KBTS_FEATURE_TAG_stch = KBTS_FOURCC('s', 't', 'c', 'h'), // Stretching Glyph Decomposition+ KBTS_FEATURE_TAG_subs = KBTS_FOURCC('s', 'u', 'b', 's'), // Subscript+ KBTS_FEATURE_TAG_sups = KBTS_FOURCC('s', 'u', 'p', 's'), // Superscript+ KBTS_FEATURE_TAG_swsh = KBTS_FOURCC('s', 'w', 's', 'h'), // Swash+ KBTS_FEATURE_TAG_test = KBTS_FOURCC('t', 'e', 's', 't'), // Test features, only for development+ KBTS_FEATURE_TAG_titl = KBTS_FOURCC('t', 'i', 't', 'l'), // Titling+ KBTS_FEATURE_TAG_tnam = KBTS_FOURCC('t', 'n', 'a', 'm'), // Traditional Name Forms+ KBTS_FEATURE_TAG_tnum = KBTS_FOURCC('t', 'n', 'u', 'm'), // Tabular Figures+ KBTS_FEATURE_TAG_trad = KBTS_FOURCC('t', 'r', 'a', 'd'), // Traditional Forms+ KBTS_FEATURE_TAG_twid = KBTS_FOURCC('t', 'w', 'i', 'd'), // Third Widths+ KBTS_FEATURE_TAG_unic = KBTS_FOURCC('u', 'n', 'i', 'c'), // Unicase+ KBTS_FEATURE_TAG_valt = KBTS_FOURCC('v', 'a', 'l', 't'), // Alternate Vertical Metrics+ KBTS_FEATURE_TAG_vapk = KBTS_FOURCC('v', 'a', 'p', 'k'), // Kerning for Alternate Proportional Vertical Metrics+ KBTS_FEATURE_TAG_vatu = KBTS_FOURCC('v', 'a', 't', 'u'), // Vattu Variants+ KBTS_FEATURE_TAG_vchw = KBTS_FOURCC('v', 'c', 'h', 'w'), // Vertical Contextual Half-width Spacing+ KBTS_FEATURE_TAG_vert = KBTS_FOURCC('v', 'e', 'r', 't'), // Vertical Alternates+ KBTS_FEATURE_TAG_vhal = KBTS_FOURCC('v', 'h', 'a', 'l'), // Alternate Vertical Half Metrics+ KBTS_FEATURE_TAG_vkna = KBTS_FOURCC('v', 'k', 'n', 'a'), // Vertical Kana Alternates+ KBTS_FEATURE_TAG_vkrn = KBTS_FOURCC('v', 'k', 'r', 'n'), // Vertical Kerning+ KBTS_FEATURE_TAG_vpal = KBTS_FOURCC('v', 'p', 'a', 'l'), // Proportional Alternate Vertical Metrics+ KBTS_FEATURE_TAG_vrt2 = KBTS_FOURCC('v', 'r', 't', '2'), // Vertical Alternates and Rotation+ KBTS_FEATURE_TAG_vrtr = KBTS_FOURCC('v', 'r', 't', 'r'), // Vertical Alternates for Rotation+ KBTS_FEATURE_TAG_zero = KBTS_FOURCC('z', 'e', 'r', 'o'), // Slashed Zero+};++typedef struct kbts__gdef kbts__gdef;+typedef struct kbts__cmap_14 kbts__cmap_14;+typedef struct kbts__gsub_gpos kbts__gsub_gpos;+typedef struct kbts__maxp kbts__maxp;+typedef struct kbts__hea kbts__hea;+typedef struct kbts_shaper_properties kbts_shaper_properties;+typedef struct kbts__feature kbts__feature;+typedef struct kbts__head kbts__head;+typedef struct kbts__langsys kbts__langsys;+typedef struct kbts_shape_config kbts_shape_config;+typedef struct kbts_glyph kbts_glyph;+typedef struct kbts_glyph_config kbts_glyph_config;+typedef struct kbts_shape_context kbts_shape_context;+typedef struct kbts_glyph_storage kbts_glyph_storage;++typedef struct kbts_allocator_op_allocate+{+ void *Pointer;+ kbts_u32 Size;+} kbts_allocator_op_allocate;++typedef struct kbts_allocator_op_free+{+ void *Pointer;+} kbts_allocator_op_free;++typedef struct kbts_allocator_op+{+ kbts_allocator_op_kind Kind;++ union+ {+ kbts_allocator_op_allocate Allocate;+ kbts_allocator_op_free Free;+ };+} kbts_allocator_op;++typedef void kbts_allocator_function(void *Data, kbts_allocator_op *Op);++typedef struct kbts_lookup_subtable_info+{+ kbts_u16 MinimumBacktrackPlusOne;+ kbts_u16 MinimumFollowupPlusOne;+} kbts_lookup_subtable_info;++typedef struct kbts_blob_table+{+ kbts_u32 OffsetFromStartOfFile;+ kbts_u32 Length;+} kbts_blob_table;++typedef struct kbts_load_font_state+{+ void *FontData;+ kbts_u32 FontDataSize;++ kbts_blob_table Tables[KBTS_BLOB_TABLE_ID_COUNT];+ kbts_u32 LookupCount;+ kbts_u32 LookupSubtableCount;+ kbts_u32 GlyphCount;+ kbts_u32 ScratchSize;++ kbts_u32 GlyphLookupMatrixSizeInBytes;+ kbts_u32 GlyphLookupSubtableMatrixSizeInBytes;+ kbts_u32 TotalSize;+} kbts_load_font_state;++typedef struct kbts_blob_header+{+ kbts_u32 Magic;+ kbts_u32 Version;++ kbts_u32 LookupCount;+ kbts_u32 LookupSubtableCount;+ kbts_u32 GlyphCount;++ kbts_u32 GposLookupIndexOffset;++ kbts_u32 GlyphLookupMatrixOffsetFromStartOfFile;+ kbts_u32 GlyphLookupSubtableMatrixOffsetFromStartOfFile;+ kbts_u32 LookupSubtableIndexOffsetsOffsetFromStartOfFile;+ kbts_u32 SubtableInfosOffsetFromStartOfFile;++ kbts_blob_table Tables[KBTS_BLOB_TABLE_ID_COUNT];+} kbts_blob_header;++typedef struct kbts_font+{+ kbts_allocator_function *Allocator;+ void *AllocatorData;++ kbts_blob_header *Blob;+ kbts_u16 *Cmap;+ kbts__cmap_14 *Cmap14;++ kbts__gsub_gpos *ShapingTables[KBTS_SHAPING_TABLE_COUNT];++ void *UserData;++ kbts_load_font_error Error;+} kbts_font;++typedef struct kbts_font_info+{+ char *Strings[KBTS_FONT_INFO_STRING_ID_COUNT];+ kbts_u16 StringLengths[KBTS_FONT_INFO_STRING_ID_COUNT];++ kbts_font_style_flags StyleFlags;+ kbts_font_weight Weight;+ kbts_font_width Width;+} kbts_font_info;++typedef struct kbts_feature_override+{+ kbts_feature_tag Tag;+ int Value;+} kbts_feature_override;++typedef struct kbts_break+{+ // The break code mostly works in relative positions, but we convert to absolute positions for the user.+ // That way, breaks can be trivially stored and compared and such and it just works.+ int Position;+ kbts_break_flags Flags;+ kbts_direction Direction; // Only valid if (Flags & KBTS_BREAK_FLAG_DIRECTION).+ kbts_direction ParagraphDirection; // Only valid if (Flags & KBTS_BREAK_FLAG_PARAGRAPH_DIRECTION).+ kbts_script Script; // Only valid if (Flags & KBTS_BREAK_FLAG_SCRIPT).+} kbts_break;++typedef struct kbts_bracket+{+ kbts_u32 Codepoint;+ kbts_u32 Position;+ kbts_u8 Direction;+ kbts_u8 Script;+} kbts_bracket;++// In the worst case, a single call to BreakAddCodepoint would generate 4 breaks.+// We buffer breaks to reorder them before returning them to the user.+// This potentially requires infinite memory, which we don't have, so you may want to tweak this constant,+// although, really, if the defaults don't work, then you have likely found very strange/adversarial text.+typedef struct kbts_break_state+{+ kbts_break Breaks[8];+ kbts_u32 BreakCount;++ kbts_direction ParagraphDirection;+ kbts_direction UserParagraphDirection;++ kbts_u32 CurrentPosition;+ kbts_u32 ParagraphStartPosition;++ kbts_u32 LastScriptBreakPosition;+ kbts_u32 LastDirectionBreakPosition;+ kbts_u8 LastScriptBreakScript;+ kbts_u8 LastDirectionBreakDirection;++ kbts_s16 ScriptPositionOffset;+ kbts_u32 ScriptCount;+ kbts_u8 ScriptSet[KBTS_MAXIMUM_CODEPOINT_SCRIPTS];++ kbts_bracket Brackets[64];+ kbts_u32 BracketCount;+ kbts_break_state_flags Flags;++ kbts_u32 FlagState; // u8(kbts_break_flags)x4+ kbts_s16 PositionOffset2;+ kbts_s16 PositionOffset3;++ kbts_u32 WordBreakHistory; // u8x4+ kbts_u16 WordBreaks; // u4x4+ kbts_u16 WordUnbreaks; // u4x4+ kbts_s16 WordBreak2PositionOffset;++ kbts_u64 LineBreaks; // u16x4+ // Instead of staying synchronized with LineBreaks/LineUnbreaks,+ // this advances every character always.+ // (This is only needed because ZWJ can create an unbreak while simultaneously being ignored.)+ kbts_u64 LineUnbreaksAsync; // u16x4+ kbts_u64 LineUnbreaks; // u16x4+ kbts_u32 LineBreakHistory; // u8(line_break_class)x4+ kbts_s16 LineBreak2PositionOffset;+ kbts_s16 LineBreak3PositionOffset;++ kbts_u8 LastDirection;+ kbts_u8 BidirectionalClass2;+ kbts_u8 BidirectionalClass1;+ kbts_s16 Bidirectional1PositionOffset;+ kbts_s16 Bidirectional2PositionOffset;++ kbts_japanese_line_break_style JapaneseLineBreakStyle;+ kbts_break_config_flags ConfigFlags;+ kbts_u8 GraphemeBreakState;+ kbts_u8 LastLineBreakClass;+ kbts_u8 LastWordBreakClass;+ kbts_u8 LastWordBreakClassIncludingIgnored;+} kbts_break_state;++typedef struct kbts_decode+{+ int Codepoint;++ int SourceCharactersConsumed;+ int Valid;+} kbts_decode;++typedef struct kbts_encode_utf8+{+ char Encoded[4];+ int EncodedLength;+ int Valid;+} kbts_encode_utf8;++typedef struct kbts_glyph_classes+{+ kbts_u16 Class;+ kbts_u16 MarkAttachmentClass;+} kbts_glyph_classes;++typedef struct kbts_glyph+{+ kbts_glyph *Prev;+ kbts_glyph *Next;++ kbts_u32 Codepoint;+ kbts_u16 Id; // Glyph index. This is what you want to use to query outline data.+ kbts_u16 Uid;++ // This field is kept and returned as-is throughout the shaping process.+ // When you are using the context API, it contains a codepoint index always!+ // To get the original user ID with the context API, you need to get the corresponding kbts_shape_codepoint+ // with kbts_ShapeGetShapeCodepoint(Context, Glyph->UserIdOrCodepointIndex, ...);+ int UserIdOrCodepointIndex;++ // Used by GPOS+ kbts_s32 OffsetX;+ kbts_s32 OffsetY;+ kbts_s32 AdvanceX;+ kbts_s32 AdvanceY;++ // Earlier on, we used to assume that, if a glyph had no advance, or had the MARK glyph class, then+ // it could be handled as a mark in layout operations. This is inaccurate.+ // Unicode makes a distinction between attached marks and standalone marks. For our purposes, attached+ // marks are marks that have found a valid base character to attach to. In practice, this means that the+ // font contains a valid display position/configuration for it in the current context.+ // In contrast, standalone marks are marks that aren't attached to anything. Fonts may still have glyphs+ // for them, in which case we want to display those just like regular glyphs that take up horizontal space+ // on the line. When fonts don't have glyphs for them, they simply stay around as zero-width glyphs.+ // Standalone marks have notably different behavior compared to attached marks, and so, once we start+ // applying positioning features, it becomes worthwhile to track exactly which glyph has attached to which.+ struct kbts_glyph *AttachGlyph; // Set by GPOS attachments.++ kbts_glyph_config *Config;++ kbts_u64 Decomposition;++ kbts_glyph_classes Classes;++ kbts_glyph_flags Flags;++ kbts_u32 ParentInfo;++ // This is set by GSUB and used by GPOS.+ // A 0-index means that we should attach to the last component in the ligature.+ //+ // From the Microsoft docs:+ // To correctly access the subtables, the client must keep track of the component associated with the mark.+ //+ // For a given mark assigned to a particular class, the appropriate base attachment point is determined by which+ // ligature component the mark is associated with. This is dependent on the original character string and subsequent+ // character- or glyph-sequence processing, not the font data alone. While a text-layout client is performing any+ // character-based preprocessing or any glyph-substitution operations using the GSUB table, the text-layout client+ // must keep track of associations of marks to particular ligature-glyph components.+ kbts_u16 LigatureUid;+ kbts_u16 LigatureComponentIndexPlusOne;+ kbts_u16 LigatureComponentCount;++ // Set in GSUB and used in GPOS, for STCH.+ kbts_joining_feature JoiningFeature;++ // Unicode properties filled in by CodepointToGlyph.+ kbts_unicode_joining_type JoiningType;+ kbts_u8 UnicodeFlags;+ kbts_u8 SyllabicClass;+ kbts_u8 SyllabicPosition;+ kbts_u8 UseClass;+ kbts_u8 CombiningClass;++ kbts_u8 MarkOrdering; // Only used temporarily in NORMALIZE for Arabic mark reordering.+} kbts_glyph;++typedef struct kbts_shape_codepoint+{+ kbts_font *Font; // Only set when (BreakFlags & KBTS_BREAK_FLAG_GRAPHEME) != 0.+ kbts_glyph_config *Config;++ int Codepoint;+ int UserId;++ kbts_break_flags BreakFlags;+ kbts_script Script; // Only set when (BreakFlags & KBTS_BREAK_FLAG_SCRIPT) != 0.+ kbts_direction Direction; // Only set when (BreakFlags & KBTS_BREAK_FLAG_DIRECTION) != 0.+ kbts_direction ParagraphDirection; // Only set when (BreakFlags & KBTS_BREAK_FLAG_PARAGRAPH_DIRECTION) != 0.+} kbts_shape_codepoint;++typedef struct kbts_shape_codepoint_iterator+{+ kbts_shape_codepoint *Codepoint;+ kbts_shape_context *Context;++ kbts_u32 EndBlockIndex;+ kbts_u32 OnePastLastCodepointIndex;+ kbts_u32 BlockIndex;+ kbts_u32 CodepointIndex;+ kbts_u32 CurrentBlockCodepointCount;+ kbts_u32 FlatCodepointIndex;+} kbts_shape_codepoint_iterator;++typedef struct kbts_glyph_iterator+{+ kbts_glyph_storage *GlyphStorage;+ kbts_glyph *CurrentGlyph;++ int LastAdvanceX;+ int X;+ int Y;+} kbts_glyph_iterator;++typedef struct kbts_arena_block_header+{+ struct kbts_arena_block_header *Prev;+ struct kbts_arena_block_header *Next;+} kbts_arena_block_header;++typedef struct kbts_arena+{+ kbts_allocator_function *Allocator;+ void *AllocatorData;++ kbts_arena_block_header BlockSentinel;+ kbts_arena_block_header FreeBlockSentinel;++ int Error;+} kbts_arena;++typedef struct kbts_glyph_storage+{+ kbts_arena Arena;++ kbts_glyph GlyphSentinel;+ kbts_glyph FreeGlyphSentinel;++ int Error;+} kbts_glyph_storage;++typedef struct kbts_glyph_parent+{+ kbts_u64 Decomposition;+ kbts_u32 Codepoint;+} kbts_glyph_parent;++typedef struct kbts_font_coverage_test+{+ kbts_font *Font;+ kbts_u32 BaseCodepoint;++ int CurrentBaseError;+ int Error;++ kbts_glyph_parent BaseParents[KBTS_MAXIMUM_RECOMPOSITION_PARENTS];+ kbts_u32 BaseParentCount;+} kbts_font_coverage_test;++typedef struct kbts_run+{+ kbts_font *Font;+ kbts_script Script;+ kbts_direction ParagraphDirection;+ kbts_direction Direction;+ kbts_break_flags Flags;++ kbts_glyph_iterator Glyphs;+} kbts_run;++//+// Context API+// The context can do everything for you. It is pretty convenient!+//++KBTS_EXPORT int kbts_SizeOfShapeContext(void);+KBTS_EXPORT kbts_shape_context *kbts_PlaceShapeContext(kbts_allocator_function *Allocator, void *AllocatorData, void *Memory);+KBTS_EXPORT kbts_shape_context *kbts_PlaceShapeContextFixedMemory(void *Memory, int Size);+KBTS_EXPORT kbts_shape_context *kbts_CreateShapeContext(kbts_allocator_function *Allocator, void *AllocatorData);+KBTS_EXPORT void kbts_DestroyShapeContext(kbts_shape_context *Context);+#ifndef KB_TEXT_SHAPE_NO_CRT+KBTS_EXPORT kbts_font *kbts_ShapePushFontFromFile(kbts_shape_context *Context, const char *FileName, int FontIndex);+#endif+KBTS_EXPORT kbts_font *kbts_ShapePushFontFromMemory(kbts_shape_context *Context, void *Memory, int Size, int FontIndex);+KBTS_EXPORT kbts_font *kbts_ShapePushFont(kbts_shape_context *Context, kbts_font *Font);+KBTS_EXPORT kbts_font *kbts_ShapePopFont(kbts_shape_context *Context);+KBTS_EXPORT void kbts_ShapeBegin(kbts_shape_context *Context, kbts_direction ParagraphDirection, kbts_language Language);+KBTS_EXPORT void kbts_ShapeEnd(kbts_shape_context *Context);+KBTS_EXPORT int kbts_ShapeRun(kbts_shape_context *Context, kbts_run *Run);+KBTS_EXPORT void kbts_ShapePushFeature(kbts_shape_context *Context, kbts_u32 FeatureTag, int Value);+KBTS_EXPORT int kbts_ShapePopFeature(kbts_shape_context *Context, kbts_u32 FeatureTag);+KBTS_EXPORT void kbts_ShapeCodepoint(kbts_shape_context *Context, int Codepoint);+KBTS_EXPORT void kbts_ShapeCodepointWithUserId(kbts_shape_context *Context, int Codepoint, int UserId);+KBTS_EXPORT void kbts_ShapeUtf32(kbts_shape_context *Context, int *Utf32, int Length);+KBTS_EXPORT void kbts_ShapeUtf32WithUserId(kbts_shape_context *Context, int *Utf32, int Length, int UserId, int UserIdIncrement);+KBTS_EXPORT void kbts_ShapeUtf8(kbts_shape_context *Context, const char *Utf8, int Length, kbts_user_id_generation_mode UserIdGenerationMode);+KBTS_EXPORT void kbts_ShapeUtf8WithUserId(kbts_shape_context *Context, const char *Utf8, int Length, int UserId, kbts_user_id_generation_mode UserIdGenerationMode);+KBTS_EXPORT kbts_shape_error kbts_ShapeError(kbts_shape_context *Context);+KBTS_EXPORT void kbts_ShapeBeginManualRuns(kbts_shape_context *Context);+KBTS_EXPORT void kbts_ShapeNextManualRun(kbts_shape_context *Context, kbts_direction Direction, kbts_script Script);+KBTS_EXPORT void kbts_ShapeEndManualRuns(kbts_shape_context *Context);+KBTS_EXPORT void kbts_ShapeManualBreak(kbts_shape_context *Context);+KBTS_EXPORT kbts_shape_codepoint_iterator kbts_ShapeCurrentCodepointsIterator(kbts_shape_context *Context);+KBTS_EXPORT int kbts_ShapeCodepointIteratorIsValid(kbts_shape_codepoint_iterator *It);+KBTS_EXPORT int kbts_ShapeCodepointIteratorNext(kbts_shape_codepoint_iterator *It, kbts_shape_codepoint *Codepoint, int *CodepointIndex);+KBTS_EXPORT int kbts_ShapeGetShapeCodepoint(kbts_shape_context *Context, int CodepointIndex, kbts_shape_codepoint *Codepoint);++//+// Direct API+//++KBTS_EXPORT kbts_shape_error kbts_ShapeDirect(kbts_shape_config *Config, kbts_glyph_storage *Storage, kbts_direction RunDirection, kbts_allocator_function *Allocator, void *AllocatorData, kbts_glyph_iterator *Output);+KBTS_EXPORT kbts_shape_error kbts_ShapeDirectFixedMemory(kbts_shape_config *Config, kbts_glyph_storage *Storage, kbts_direction RunDirection, void *Memory, int MemorySize, kbts_glyph_iterator *Output);++// A font holds all data that corresponds to a given font file.+#ifndef KB_TEXT_SHAPE_NO_CRT+KBTS_EXPORT kbts_font kbts_FontFromFile(const char *FileName, int FontIndex, kbts_allocator_function *Allocator, void *AllocatorData, void **FileData, int *FileSize);+#endif+KBTS_EXPORT int kbts_FontCount(void *FileData, int FileSize);+KBTS_EXPORT kbts_font kbts_FontFromMemory(void *FileData, int FileSize, int FontIndex, kbts_allocator_function *Allocator, void *AllocatorData);+KBTS_EXPORT void kbts_FreeFont(kbts_font *Font);+KBTS_EXPORT int kbts_FontIsValid(kbts_font *Font);+KBTS_EXPORT kbts_load_font_error kbts_LoadFont(kbts_font *Font, kbts_load_font_state *State, void *FontData, int FontDataSize, int FontIndex, int *ScratchSize_, int *OutputSize_);+KBTS_EXPORT kbts_load_font_error kbts_PlaceBlob(kbts_font *Font, kbts_load_font_state *State, void *ScratchMemory, void *OutputMemory);+KBTS_EXPORT void kbts_GetFontInfo(kbts_font *Font, kbts_font_info *Info);++// A shape_config is a bag of pre-computed data for a specific shaping setup.+KBTS_EXPORT int kbts_SizeOfShapeConfig(kbts_font *Font, kbts_script Script, kbts_language Language);+KBTS_EXPORT kbts_shape_config *kbts_PlaceShapeConfig(kbts_font *Font, kbts_script Script, kbts_language Language, void *Memory);+KBTS_EXPORT kbts_shape_config *kbts_CreateShapeConfig(kbts_font *Font, kbts_script Script, kbts_language Language, kbts_allocator_function *Allocator, void *AllocatorData);+KBTS_EXPORT void kbts_DestroyShapeConfig(kbts_shape_config *Config);++// A glyph_storage holds and recycles glyph data.+KBTS_EXPORT int kbts_InitializeGlyphStorage(kbts_glyph_storage *Storage, kbts_allocator_function *Allocator, void *AllocatorData);+KBTS_EXPORT int kbts_InitializeGlyphStorageFixedMemory(kbts_glyph_storage *Storage, void *Memory, int MemorySize);+KBTS_EXPORT kbts_glyph *kbts_PushGlyph(kbts_glyph_storage *Storage, kbts_font *Font, int Codepoint, kbts_glyph_config *Config, int UserId);+KBTS_EXPORT void kbts_ClearActiveGlyphs(kbts_glyph_storage *Storage);+KBTS_EXPORT void kbts_FreeAllGlyphs(kbts_glyph_storage *Storage);+KBTS_EXPORT kbts_glyph kbts_CodepointToGlyph(kbts_font *Font, int Codepoint, kbts_glyph_config *Config, int UserId);+KBTS_EXPORT int kbts_CodepointToGlyphId(kbts_font *Font, int Codepoint);+KBTS_EXPORT kbts_glyph_iterator kbts_ActiveGlyphIterator(kbts_glyph_storage *Storage);++// A glyph_config specifies glyph-specific shaping parameters.+// A single glyph_config can be shared by multiple glyphs.+KBTS_EXPORT int kbts_SizeOfGlyphConfig(kbts_feature_override *Overrides, int OverrideCount);+KBTS_EXPORT kbts_glyph_config *kbts_PlaceGlyphConfig(kbts_feature_override *Overrides, int OverrideCount, void *Memory);+KBTS_EXPORT kbts_glyph_config *kbts_CreateGlyphConfig(kbts_feature_override *Overrides, int OverrideCount, kbts_allocator_function *Allocator, void *AllocatorData);+KBTS_EXPORT void kbts_DestroyGlyphConfig(kbts_glyph_config *Config);++//+// Glyph iterator+//++KBTS_EXPORT int kbts_GlyphIteratorNext(kbts_glyph_iterator *It, kbts_glyph **Glyph);+KBTS_EXPORT int kbts_GlyphIteratorIsValid(kbts_glyph_iterator *It);++//+// Segmentation+//++// This is a quick guess that stops at the first glyph that has a strong script/direction associated to it.+// It is convenient, but only works if you are sure your input text is mono-script and mono-direction.+KBTS_EXPORT void kbts_GuessTextProperties(void *Text, int TextSizeInBytes, kbts_text_format Format, kbts_direction *Direction, kbts_script *Script);+KBTS_EXPORT void kbts_GuessTextPropertiesUtf32(const int *Utf32, int Utf32Count, kbts_direction *Direction, kbts_script *Script);+KBTS_EXPORT void kbts_GuessTextPropertiesUtf8(const char *Utf8, int Utf8Length, kbts_direction *Direction, kbts_script *Script);++KBTS_EXPORT void kbts_BreakBegin(kbts_break_state *State, kbts_direction ParagraphDirection, kbts_japanese_line_break_style JapaneseLineBreakStyle, kbts_break_config_flags ConfigFlags);+KBTS_EXPORT void kbts_BreakAddCodepoint(kbts_break_state *State, int Codepoint, int PositionIncrement, int EndOfText);+KBTS_EXPORT void kbts_BreakEnd(kbts_break_state *State);+KBTS_EXPORT int kbts_Break(kbts_break_state *State, kbts_break *Break);+KBTS_EXPORT void kbts_BreakEntireString(kbts_direction Direction, kbts_japanese_line_break_style JapaneseLineBreakStyle, kbts_break_config_flags ConfigFlags, const void *Input, int InputSizeInBytes, kbts_text_format InputFormat, kbts_break *Breaks, int BreakCapacity, int *BreakCount, kbts_break_flags *BreakFlags, int BreakFlagCapacity, int *BreakFlagCount);+KBTS_EXPORT void kbts_BreakEntireStringUtf32(kbts_direction Direction, kbts_japanese_line_break_style JapaneseLineBreakStyle, kbts_break_config_flags ConfigFlags, const int *Utf32, int Utf32Count, kbts_break *Breaks, int BreakCapacity, int *BreakCount, kbts_break_flags *BreakFlags, int BreakFlagCapacity, int *BreakFlagCount);+KBTS_EXPORT void kbts_BreakEntireStringUtf8(kbts_direction Direction, kbts_japanese_line_break_style JapaneseLineBreakStyle, kbts_break_config_flags ConfigFlags, const char *Utf8, int Utf8Length, kbts_break *Breaks, int BreakCapacity, int *BreakCount, kbts_break_flags *BreakFlags, int BreakFlagCapacity, int *BreakFlagCount);++//+// Other stuff+//++// Quick test for font support of a sequence of codepoints.+KBTS_EXPORT void kbts_FontCoverageTestBegin(kbts_font_coverage_test *Test, kbts_font *Font);+KBTS_EXPORT void kbts_FontCoverageTestCodepoint(kbts_font_coverage_test *Test, int Codepoint);+KBTS_EXPORT int kbts_FontCoverageTestEnd(kbts_font_coverage_test *Test);++KBTS_EXPORT kbts_decode kbts_DecodeUtf8(const char *Utf8, kbts_un Length);+KBTS_EXPORT kbts_encode_utf8 kbts_EncodeUtf8(int Codepoint);+KBTS_EXPORT kbts_direction kbts_ScriptDirection(kbts_script Script);+KBTS_EXPORT int kbts_ScriptIsComplex(kbts_script Script);+KBTS_EXPORT kbts_script kbts_ScriptTagToScript(kbts_script_tag Tag);++#endif
+ cbits/kb_text_shape.inc view
@@ -0,0 +1,26055 @@+/* kb_text_shape - v2.06 - text segmentation and shaping+ by Jimmy Lefevre+*/++#ifdef _MSC_VER+#define KBTS__UNUSED(X) (void)sizeof((X))+#else+#define KBTS__UNUSED(X) (void)(X)+#endif+# define KBTS__FOR(I, Start, End) for(kbts_un I = (Start); I < (End); ++I)+# ifdef __cplusplus+# define KBTS__ZERO {}+# define KBTS__ZERO_TYPE(T) T{}+# else+# define KBTS__ZERO {0}+# define KBTS__ZERO_TYPE(T) (T){0}+# endif+# define KBTS__MAX(A, B) (((A) < (B)) ? (B) : (A))+# define KBTS__MIN(A, B) (((A) < (B)) ? (A) : (B))+# define KBTS__ARRAY_LENGTH(A) (sizeof(A)/sizeof(*(A)))+# define KBTS__POINTER_AFTER(Type, X) ((Type *)((X) + 1))+# define KBTS__POINTER_OFFSET(Type, Base, Offset) ((Type *)((char *)(Base) + (Offset)))+# define KBTS__POINTER_DIFF32(Pointer, Base) ((kbts_u32)((char *)(Pointer) - (char *)(Base)))+# define KBTS__POINTER_DIFF(Pointer, Base) ((kbts_un)((char *)(Pointer) - (char *)(Base)))+# define KBTS__ALIGN_POINTER(Type, Pointer, Align) (Type *)(((kbts_un)(Pointer) + ((Align) - 1)) & ~((Align) - 1))+# define KBTS__PASTE_1(A, B) A##B+# define KBTS__PASTE_0(A, B) KBTS__PASTE_1(A, B)+# define KBTS__PASTE(A, B) KBTS__PASTE_0(A, B)+# define KBTS__IN_SET(X, Set) ((1u << (X)) & (Set))+# define KBTS__SET32_0(Arg) | (1u << (Arg)) KBTS__SET32_1+# define KBTS__SET32_1(Arg) | (1u << (Arg)) KBTS__SET32_0+# define KBTS__SET32_0End+# define KBTS__SET32_1End+# define KBTS__SET32(Args) (0u KBTS__PASTE(KBTS__SET32_0 Args, End))+# define KBTS__IN_SET64(X, Set) ((1ull << (X)) & (Set))+# define KBTS__SET64_0(Arg) | (1ull << (Arg)) KBTS__SET64_1+# define KBTS__SET64_1(Arg) | (1ull << (Arg)) KBTS__SET64_0+# define KBTS__SET64_0End+# define KBTS__SET64_1End+# define KBTS__SET64(Args) (0u KBTS__PASTE(KBTS__SET64_0 Args, End))+#define KBTS__U32BE(X) kbts__ByteSwap32((X))+#define KBTS__U32LE(X) (X)++#define KBTS_LOOKUP_STACK_SIZE 64++# ifndef KBTS_ASSERT+#ifndef KB_TEXT_SHAPE_NO_CRT+# include <assert.h>+# define KBTS_ASSERT(Cond) assert(Cond)+#else+#define KBTS_ASSERT(Cond)+#endif+# endif++#ifndef KB_TEXT_SHAPE_NO_CRT+#include <stdio.h>+#endif++#ifndef KBTS_MEMSET+#include <string.h>+#define KBTS_MEMSET memset+#endif++#ifndef KBTS_MEMCPY+#include <string.h>+#define KBTS_MEMCPY memcpy+#endif++#ifndef KB_TEXT_SHAPE_NO_CRT+#ifndef KBTS_MALLOC+#include <stdlib.h>+#define KBTS_MALLOC(Data, Size) malloc((Size))+#define KBTS_FREE(Data, Pointer) free((Pointer))+#endif+#else+#ifndef KBTS_MALLOC+// Nerf the default allocator to a null allocator.+#define KBTS_MALLOC(Data, Size) 0+#define KBTS_FREE(Data, Pointer)+#endif+#endif++#ifndef kbts__ByteSwap16+# if defined(_MSC_VER) && !defined(__clang__)+#include <intrin.h>+KBTS_INLINE kbts_u16 kbts__ByteSwap16(kbts_u16 X)+{+ kbts_u16 Result = (kbts_u16)((X >> 8) | (X << 8));+ return Result;+}+KBTS_INLINE kbts_u32 kbts__ByteSwap32(kbts_u32 X)+{+ kbts_u32 Result = (X >> 24) |+ ((X & 0xFF0000) >> 8) |+ ((X & 0xFF00) << 8) |+ ((X & 0xFF) << 24);+ return Result;+}+# define kbts__PopCount32(X) (kbts_un)__popcnt(X)+# elif defined(__clang__) || defined(__GNUC__)+# define kbts__ByteSwap16(X) __builtin_bswap16(X)+# define kbts__ByteSwap32(X) __builtin_bswap32(X)+# define kbts__PopCount32(X) (kbts_un)__builtin_popcount(X)+# else+# error Unsupported compiler!+# endif+#endif++#ifndef kbts__MsbPositionOrZero32+# if defined(_MSC_VER) && !defined(__clang__)+#include <intrin.h>+KBTS_INLINE kbts_u32 kbts__MsbPositionOrZero32(kbts_u32 X)+{+ unsigned long Result;+ if(!_BitScanReverse(&Result, X))+ {+ Result = 0;+ }+ return (kbts_u32)Result;+}+# elif defined(__clang__) || defined(__GNUC__)+KBTS_INLINE kbts_u32 kbts__MsbPositionOrZero32(kbts_u32 X)+{+ kbts_u32 Result = 0;+ if(X)+ {+ Result = 31 - __builtin_clz(X);+ }+ return Result;+}+# else+# error Unsupported compiler!+# endif+#endif++#define KBTS__FEATURE_FLAG0(Feature) (1ull << KBTS__FEATURE_ID_##Feature)+#define KBTS__FEATURE_FLAG1(Feature) (1ull << (KBTS__FEATURE_ID_##Feature - 64))+#define KBTS__FEATURE_FLAG2(Feature) (1ull << (KBTS__FEATURE_ID_##Feature - 128))+#define KBTS__FEATURE_FLAG3(Feature) (1ull << (KBTS__FEATURE_ID_##Feature - 192))++// #define KBTS_SANITY_CHECK+// #define KBTS_DUMP++# ifdef KBTS_DUMP+# define KBTS_DUMPF(...) printf(__VA_ARGS__), fflush(stdout)+# else+# define KBTS_DUMPF(...)+# endif++#ifndef KBTS_INSTRUMENT_BLOCK_BEGIN+#define KBTS_INSTRUMENT_BLOCK_BEGIN(Name)+#define KBTS_INSTRUMENT_BLOCK_END(Name)+#define KBTS_INSTRUMENT_FUNCTION_BEGIN+#define KBTS_INSTRUMENT_FUNCTION_END+#endif++#define KBTS__GLYPH_FEATURE_MASK ((KBTS_GLYPH_FLAG_CFAR << 1) - 1)+// In USE, glyphs are mostly not pre-flagged for feature application.+// However, we do want to flag rphf/pref results for reordering, so we want to+// keep all of the flags as usual, and only use these feature flags for filtering.+#define KBTS__USE_GLYPH_FEATURE_MASK (KBTS_GLYPH_FLAG_ISOL | KBTS_GLYPH_FLAG_FINA | KBTS_GLYPH_FLAG_FIN2 | KBTS_GLYPH_FLAG_FIN3 | \+ KBTS_GLYPH_FLAG_MEDI | KBTS_GLYPH_FLAG_MED2 | KBTS_GLYPH_FLAG_INIT | KBTS_GLYPH_FLAG_NUMR | \+ KBTS_GLYPH_FLAG_DNOM | KBTS_GLYPH_FLAG_FRAC)+#define KBTS__JOINING_FEATURE_MASK (KBTS_GLYPH_FLAG_ISOL | KBTS_GLYPH_FLAG_FINA | KBTS_GLYPH_FLAG_FIN2 | KBTS_GLYPH_FLAG_FIN3 | \+ KBTS_GLYPH_FLAG_MEDI | KBTS_GLYPH_FLAG_MED2 | KBTS_GLYPH_FLAG_INIT)+#define KBTS__JOINING_FEATURE_TO_GLYPH_FLAG(Feature) (1 << ((Feature) - 1))++typedef kbts_u8 kbts__reph_position;+enum kbts__reph_position_enum+{+ KBTS__REPH_POSITION_AFTER_POST,+ KBTS__REPH_POSITION_BEFORE_POST,+ KBTS__REPH_POSITION_BEFORE_SUBJOINED,+ KBTS__REPH_POSITION_AFTER_SUBJOINED,+ KBTS__REPH_POSITION_AFTER_MAIN,++ KBTS__REPH_POSITION_COUNT,+};++typedef kbts_u8 kbts__reph_encoding;+enum kbts__reph_encoding_enum+{+ KBTS__REPH_ENCODING_IMPLICIT,+ KBTS__REPH_ENCODING_EXPLICIT,+ KBTS__REPH_ENCODING_LOGICAL_REPHA,+ KBTS__REPH_ENCODING_VISUAL_REPHA,++ KBTS__REPH_ENCODING_COUNT,+};++typedef kbts_u8 kbts__syllabic_position;+enum kbts__syllabic_position_enum+{+ KBTS__SYLLABIC_POSITION_NONE,++ KBTS__SYLLABIC_POSITION_RA_TO_BECOME_REPH,++ KBTS__SYLLABIC_POSITION_PREBASE_MATRA,+ KBTS__SYLLABIC_POSITION_PREBASE_CONSONANT,++ KBTS__SYLLABIC_POSITION_SYLLABLE_BASE,+ KBTS__SYLLABIC_POSITION_AFTER_MAIN,++ KBTS__SYLLABIC_POSITION_ABOVEBASE_CONSONANT,++ KBTS__SYLLABIC_POSITION_BEFORE_SUBJOINED,+ KBTS__SYLLABIC_POSITION_BELOWBASE_CONSONANT,+ KBTS__SYLLABIC_POSITION_AFTER_SUBJOINED,++ KBTS__SYLLABIC_POSITION_BEFORE_POST,+ KBTS__SYLLABIC_POSITION_POSTBASE_CONSONANT,+ KBTS__SYLLABIC_POSITION_AFTER_POST,++ KBTS__SYLLABIC_POSITION_FINAL_CONSONANT,+ KBTS__SYLLABIC_POSITION_SMVD,++ KBTS__SYLLABIC_POSITION_COUNT,+};+++typedef kbts_u32 kbts__feature_id;+enum kbts__feature_id_enum+{+ KBTS__FEATURE_ID_UNREGISTERED, // Features that aren't pre-defined in the OpenType spec+ KBTS__FEATURE_ID_isol, // Isolated Forms+ KBTS__FEATURE_ID_fina, // Terminal Forms+ KBTS__FEATURE_ID_fin2, // Terminal Forms #2+ KBTS__FEATURE_ID_fin3, // Terminal Forms #3+ KBTS__FEATURE_ID_medi, // Medial Forms+ KBTS__FEATURE_ID_med2, // Medial Forms #2+ KBTS__FEATURE_ID_init, // Initial Forms+ KBTS__FEATURE_ID_ljmo, // Leading Jamo Forms+ KBTS__FEATURE_ID_vjmo, // Vowel Jamo Forms+ KBTS__FEATURE_ID_tjmo, // Trailing Jamo Forms+ KBTS__FEATURE_ID_rphf, // Reph Form+ KBTS__FEATURE_ID_blwf, // Below-base Forms+ KBTS__FEATURE_ID_half, // Half Forms+ KBTS__FEATURE_ID_pstf, // Post-base Forms+ KBTS__FEATURE_ID_abvf, // Above-base Forms+ KBTS__FEATURE_ID_pref, // Pre-base Forms+ KBTS__FEATURE_ID_numr, // Numerators+ KBTS__FEATURE_ID_frac, // Fractions+ KBTS__FEATURE_ID_dnom, // Denominators+ KBTS__FEATURE_ID_cfar, // Conjunct Form After Ro+ KBTS__FEATURE_ID_aalt, // Access All Alternates+ KBTS__FEATURE_ID_abvm, // Above-base Mark Positioning+ KBTS__FEATURE_ID_abvs, // Above-base Substitutions+ KBTS__FEATURE_ID_afrc, // Alternative Fractions+ KBTS__FEATURE_ID_akhn, // Akhand+ KBTS__FEATURE_ID_apkn, // Kerning for Alternate Proportional Widths+ KBTS__FEATURE_ID_blwm, // Below-base Mark Positioning+ KBTS__FEATURE_ID_blws, // Below-base Substitutions+ KBTS__FEATURE_ID_calt, // Contextual Alternates+ KBTS__FEATURE_ID_case, // Case-sensitive Forms+ KBTS__FEATURE_ID_ccmp, // Glyph Composition / Decomposition+ KBTS__FEATURE_ID_chws, // Contextual Half-width Spacing+ KBTS__FEATURE_ID_cjct, // Conjunct Forms+ KBTS__FEATURE_ID_clig, // Contextual Ligatures+ KBTS__FEATURE_ID_cpct, // Centered CJK Punctuation+ KBTS__FEATURE_ID_cpsp, // Capital Spacing+ KBTS__FEATURE_ID_cswh, // Contextual Swash+ KBTS__FEATURE_ID_curs, // Cursive Positioning+ KBTS__FEATURE_ID_cv01, // Character Variant 1+ KBTS__FEATURE_ID_cv02, // Character Variant 2+ KBTS__FEATURE_ID_cv03, // Character Variant 3+ KBTS__FEATURE_ID_cv04, // Character Variant 4+ KBTS__FEATURE_ID_cv05, // Character Variant 5+ KBTS__FEATURE_ID_cv06, // Character Variant 6+ KBTS__FEATURE_ID_cv07, // Character Variant 7+ KBTS__FEATURE_ID_cv08, // Character Variant 8+ KBTS__FEATURE_ID_cv09, // Character Variant 9+ KBTS__FEATURE_ID_cv10, // Character Variant 10+ KBTS__FEATURE_ID_cv11, // Character Variant 11+ KBTS__FEATURE_ID_cv12, // Character Variant 12+ KBTS__FEATURE_ID_cv13, // Character Variant 13+ KBTS__FEATURE_ID_cv14, // Character Variant 14+ KBTS__FEATURE_ID_cv15, // Character Variant 15+ KBTS__FEATURE_ID_cv16, // Character Variant 16+ KBTS__FEATURE_ID_cv17, // Character Variant 17+ KBTS__FEATURE_ID_cv18, // Character Variant 18+ KBTS__FEATURE_ID_cv19, // Character Variant 19+ KBTS__FEATURE_ID_cv20, // Character Variant 20+ KBTS__FEATURE_ID_cv21, // Character Variant 21+ KBTS__FEATURE_ID_cv22, // Character Variant 22+ KBTS__FEATURE_ID_cv23, // Character Variant 23+ KBTS__FEATURE_ID_cv24, // Character Variant 24+ KBTS__FEATURE_ID_cv25, // Character Variant 25+ KBTS__FEATURE_ID_cv26, // Character Variant 26+ KBTS__FEATURE_ID_cv27, // Character Variant 27+ KBTS__FEATURE_ID_cv28, // Character Variant 28+ KBTS__FEATURE_ID_cv29, // Character Variant 29+ KBTS__FEATURE_ID_cv30, // Character Variant 30+ KBTS__FEATURE_ID_cv31, // Character Variant 31+ KBTS__FEATURE_ID_cv32, // Character Variant 32+ KBTS__FEATURE_ID_cv33, // Character Variant 33+ KBTS__FEATURE_ID_cv34, // Character Variant 34+ KBTS__FEATURE_ID_cv35, // Character Variant 35+ KBTS__FEATURE_ID_cv36, // Character Variant 36+ KBTS__FEATURE_ID_cv37, // Character Variant 37+ KBTS__FEATURE_ID_cv38, // Character Variant 38+ KBTS__FEATURE_ID_cv39, // Character Variant 39+ KBTS__FEATURE_ID_cv40, // Character Variant 40+ KBTS__FEATURE_ID_cv41, // Character Variant 41+ KBTS__FEATURE_ID_cv42, // Character Variant 42+ KBTS__FEATURE_ID_cv43, // Character Variant 43+ KBTS__FEATURE_ID_cv44, // Character Variant 44+ KBTS__FEATURE_ID_cv45, // Character Variant 45+ KBTS__FEATURE_ID_cv46, // Character Variant 46+ KBTS__FEATURE_ID_cv47, // Character Variant 47+ KBTS__FEATURE_ID_cv48, // Character Variant 48+ KBTS__FEATURE_ID_cv49, // Character Variant 49+ KBTS__FEATURE_ID_cv50, // Character Variant 50+ KBTS__FEATURE_ID_cv51, // Character Variant 51+ KBTS__FEATURE_ID_cv52, // Character Variant 52+ KBTS__FEATURE_ID_cv53, // Character Variant 53+ KBTS__FEATURE_ID_cv54, // Character Variant 54+ KBTS__FEATURE_ID_cv55, // Character Variant 55+ KBTS__FEATURE_ID_cv56, // Character Variant 56+ KBTS__FEATURE_ID_cv57, // Character Variant 57+ KBTS__FEATURE_ID_cv58, // Character Variant 58+ KBTS__FEATURE_ID_cv59, // Character Variant 59+ KBTS__FEATURE_ID_cv60, // Character Variant 60+ KBTS__FEATURE_ID_cv61, // Character Variant 61+ KBTS__FEATURE_ID_cv62, // Character Variant 62+ KBTS__FEATURE_ID_cv63, // Character Variant 63+ KBTS__FEATURE_ID_cv64, // Character Variant 64+ KBTS__FEATURE_ID_cv65, // Character Variant 65+ KBTS__FEATURE_ID_cv66, // Character Variant 66+ KBTS__FEATURE_ID_cv67, // Character Variant 67+ KBTS__FEATURE_ID_cv68, // Character Variant 68+ KBTS__FEATURE_ID_cv69, // Character Variant 69+ KBTS__FEATURE_ID_cv70, // Character Variant 70+ KBTS__FEATURE_ID_cv71, // Character Variant 71+ KBTS__FEATURE_ID_cv72, // Character Variant 72+ KBTS__FEATURE_ID_cv73, // Character Variant 73+ KBTS__FEATURE_ID_cv74, // Character Variant 74+ KBTS__FEATURE_ID_cv75, // Character Variant 75+ KBTS__FEATURE_ID_cv76, // Character Variant 76+ KBTS__FEATURE_ID_cv77, // Character Variant 77+ KBTS__FEATURE_ID_cv78, // Character Variant 78+ KBTS__FEATURE_ID_cv79, // Character Variant 79+ KBTS__FEATURE_ID_cv80, // Character Variant 80+ KBTS__FEATURE_ID_cv81, // Character Variant 81+ KBTS__FEATURE_ID_cv82, // Character Variant 82+ KBTS__FEATURE_ID_cv83, // Character Variant 83+ KBTS__FEATURE_ID_cv84, // Character Variant 84+ KBTS__FEATURE_ID_cv85, // Character Variant 85+ KBTS__FEATURE_ID_cv86, // Character Variant 86+ KBTS__FEATURE_ID_cv87, // Character Variant 87+ KBTS__FEATURE_ID_cv88, // Character Variant 88+ KBTS__FEATURE_ID_cv89, // Character Variant 89+ KBTS__FEATURE_ID_cv90, // Character Variant 90+ KBTS__FEATURE_ID_cv91, // Character Variant 91+ KBTS__FEATURE_ID_cv92, // Character Variant 92+ KBTS__FEATURE_ID_cv93, // Character Variant 93+ KBTS__FEATURE_ID_cv94, // Character Variant 94+ KBTS__FEATURE_ID_cv95, // Character Variant 95+ KBTS__FEATURE_ID_cv96, // Character Variant 96+ KBTS__FEATURE_ID_cv97, // Character Variant 97+ KBTS__FEATURE_ID_cv98, // Character Variant 98+ KBTS__FEATURE_ID_cv99, // Character Variant 99+ KBTS__FEATURE_ID_c2pc, // Petite Capitals From Capitals+ KBTS__FEATURE_ID_c2sc, // Small Capitals From Capitals+ KBTS__FEATURE_ID_dist, // Distances+ KBTS__FEATURE_ID_dlig, // Discretionary Ligatures+ KBTS__FEATURE_ID_dtls, // Dotless Forms+ KBTS__FEATURE_ID_expt, // Expert Forms+ KBTS__FEATURE_ID_falt, // Final Glyph on Line Alternates+ KBTS__FEATURE_ID_flac, // Flattened Accent Forms+ KBTS__FEATURE_ID_fwid, // Full Widths+ KBTS__FEATURE_ID_haln, // Halant Forms+ KBTS__FEATURE_ID_halt, // Alternate Half Widths+ KBTS__FEATURE_ID_hist, // Historical Forms+ KBTS__FEATURE_ID_hkna, // Horizontal Kana Alternates+ KBTS__FEATURE_ID_hlig, // Historical Ligatures+ KBTS__FEATURE_ID_hngl, // Hangul+ KBTS__FEATURE_ID_hojo, // Hojo Kanji Forms (JIS X 0212-1990 Kanji Forms)+ KBTS__FEATURE_ID_hwid, // Half Widths+ KBTS__FEATURE_ID_ital, // Italics+ KBTS__FEATURE_ID_jalt, // Justification Alternates+ KBTS__FEATURE_ID_jp78, // JIS78 Forms+ KBTS__FEATURE_ID_jp83, // JIS83 Forms+ KBTS__FEATURE_ID_jp90, // JIS90 Forms+ KBTS__FEATURE_ID_jp04, // JIS2004 Forms+ KBTS__FEATURE_ID_kern, // Kerning+ KBTS__FEATURE_ID_lfbd, // Left Bounds+ KBTS__FEATURE_ID_liga, // Standard Ligatures+ KBTS__FEATURE_ID_lnum, // Lining Figures+ KBTS__FEATURE_ID_locl, // Localized Forms+ KBTS__FEATURE_ID_ltra, // Left-to-right Alternates+ KBTS__FEATURE_ID_ltrm, // Left-to-right Mirrored Forms+ KBTS__FEATURE_ID_mark, // Mark Positioning+ KBTS__FEATURE_ID_mgrk, // Mathematical Greek+ KBTS__FEATURE_ID_mkmk, // Mark to Mark Positioning+ KBTS__FEATURE_ID_mset, // Mark Positioning via Substitution+ KBTS__FEATURE_ID_nalt, // Alternate Annotation Forms+ KBTS__FEATURE_ID_nlck, // NLC Kanji Forms+ KBTS__FEATURE_ID_nukt, // Nukta Forms+ KBTS__FEATURE_ID_onum, // Oldstyle Figures+ KBTS__FEATURE_ID_opbd, // Optical Bounds+ KBTS__FEATURE_ID_ordn, // Ordinals+ KBTS__FEATURE_ID_ornm, // Ornaments+ KBTS__FEATURE_ID_palt, // Proportional Alternate Widths+ KBTS__FEATURE_ID_pcap, // Petite Capitals+ KBTS__FEATURE_ID_pkna, // Proportional Kana+ KBTS__FEATURE_ID_pnum, // Proportional Figures+ KBTS__FEATURE_ID_pres, // Pre-base Substitutions+ KBTS__FEATURE_ID_psts, // Post-base Substitutions+ KBTS__FEATURE_ID_pwid, // Proportional Widths+ KBTS__FEATURE_ID_qwid, // Quarter Widths+ KBTS__FEATURE_ID_rand, // Randomize+ KBTS__FEATURE_ID_rclt, // Required Contextual Alternates+ KBTS__FEATURE_ID_rkrf, // Rakar Forms+ KBTS__FEATURE_ID_rlig, // Required Ligatures+ KBTS__FEATURE_ID_rtbd, // Right Bounds+ KBTS__FEATURE_ID_rtla, // Right-to-left Alternates+ KBTS__FEATURE_ID_rtlm, // Right-to-left Mirrored Forms+ KBTS__FEATURE_ID_ruby, // Ruby Notation Forms+ KBTS__FEATURE_ID_rvrn, // Required Variation Alternates+ KBTS__FEATURE_ID_salt, // Stylistic Alternates+ KBTS__FEATURE_ID_sinf, // Scientific Inferiors+ KBTS__FEATURE_ID_size, // Optical size+ KBTS__FEATURE_ID_smcp, // Small Capitals+ KBTS__FEATURE_ID_smpl, // Simplified Forms+ KBTS__FEATURE_ID_ss01, // Stylistic Set 1+ KBTS__FEATURE_ID_ss02, // Stylistic Set 2+ KBTS__FEATURE_ID_ss03, // Stylistic Set 3+ KBTS__FEATURE_ID_ss04, // Stylistic Set 4+ KBTS__FEATURE_ID_ss05, // Stylistic Set 5+ KBTS__FEATURE_ID_ss06, // Stylistic Set 6+ KBTS__FEATURE_ID_ss07, // Stylistic Set 7+ KBTS__FEATURE_ID_ss08, // Stylistic Set 8+ KBTS__FEATURE_ID_ss09, // Stylistic Set 9+ KBTS__FEATURE_ID_ss10, // Stylistic Set 10+ KBTS__FEATURE_ID_ss11, // Stylistic Set 11+ KBTS__FEATURE_ID_ss12, // Stylistic Set 12+ KBTS__FEATURE_ID_ss13, // Stylistic Set 13+ KBTS__FEATURE_ID_ss14, // Stylistic Set 14+ KBTS__FEATURE_ID_ss15, // Stylistic Set 15+ KBTS__FEATURE_ID_ss16, // Stylistic Set 16+ KBTS__FEATURE_ID_ss17, // Stylistic Set 17+ KBTS__FEATURE_ID_ss18, // Stylistic Set 18+ KBTS__FEATURE_ID_ss19, // Stylistic Set 19+ KBTS__FEATURE_ID_ss20, // Stylistic Set 20+ KBTS__FEATURE_ID_ssty, // Math Script-style Alternates+ KBTS__FEATURE_ID_stch, // Stretching Glyph Decomposition+ KBTS__FEATURE_ID_subs, // Subscript+ KBTS__FEATURE_ID_sups, // Superscript+ KBTS__FEATURE_ID_swsh, // Swash+ KBTS__FEATURE_ID_test, // Test features, only for development+ KBTS__FEATURE_ID_titl, // Titling+ KBTS__FEATURE_ID_tnam, // Traditional Name Forms+ KBTS__FEATURE_ID_tnum, // Tabular Figures+ KBTS__FEATURE_ID_trad, // Traditional Forms+ KBTS__FEATURE_ID_twid, // Third Widths+ KBTS__FEATURE_ID_unic, // Unicase+ KBTS__FEATURE_ID_valt, // Alternate Vertical Metrics+ KBTS__FEATURE_ID_vapk, // Kerning for Alternate Proportional Vertical Metrics+ KBTS__FEATURE_ID_vatu, // Vattu Variants+ KBTS__FEATURE_ID_vchw, // Vertical Contextual Half-width Spacing+ KBTS__FEATURE_ID_vert, // Vertical Alternates+ KBTS__FEATURE_ID_vhal, // Alternate Vertical Half Metrics+ KBTS__FEATURE_ID_vkna, // Vertical Kana Alternates+ KBTS__FEATURE_ID_vkrn, // Vertical Kerning+ KBTS__FEATURE_ID_vpal, // Proportional Alternate Vertical Metrics+ KBTS__FEATURE_ID_vrt2, // Vertical Alternates and Rotation+ KBTS__FEATURE_ID_vrtr, // Vertical Alternates for Rotation+ KBTS__FEATURE_ID_zero, // Slashed Zero+ KBTS__FEATURE_ID_COUNT,+};++typedef struct kbts__feature_set+{+ kbts_u64 Flags[(KBTS__FEATURE_ID_COUNT + 63) / 64];+} kbts__feature_set;+typedef kbts_u8 kbts__op_kind;+enum kbts__op_kind_enum+{+ KBTS__OP_KIND_END,+ KBTS__OP_KIND_PRE_NORMALIZE_DOTTED_CIRCLES,+ KBTS__OP_KIND_NORMALIZE,+ KBTS__OP_KIND_NORMALIZE_HANGUL,+ KBTS__OP_KIND_FLAG_JOINING_LETTERS,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES_WITH_USER,+ KBTS__OP_KIND_GPOS_METRICS,+ KBTS__OP_KIND_GPOS_FEATURES,+ KBTS__OP_KIND_POST_GPOS_FIXUP,+ KBTS__OP_KIND_STCH_POSTPASS,+ KBTS__OP_KIND_BEGIN_CLUSTER,+ KBTS__OP_KIND_END_CLUSTER,+ KBTS__OP_KIND_END_SYLLABLE,+ KBTS__OP_KIND_COUNT,+};+typedef struct kbts__feature_stage+{+ kbts_u32 FeatureCount;+ kbts__feature_set Features;+} kbts__feature_stage;+typedef struct kbts__op_list+{+ kbts_u32 TotalFeatureCount;+ kbts_u32 FeatureStageCount;+ kbts__feature_stage *FeatureStages;+ kbts_u32 OpCount;+ kbts__op_kind *Ops;+} kbts__op_list;+static kbts__op_kind kbts__Ops_Default[] = {+ KBTS__OP_KIND_NORMALIZE,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES_WITH_USER,+ KBTS__OP_KIND_GPOS_METRICS,+ KBTS__OP_KIND_GPOS_FEATURES,+ KBTS__OP_KIND_POST_GPOS_FIXUP,+};+static kbts__feature_stage kbts__FeatureStages_Default[] = {+ {1, {{0ull, 0ull, 0ull, 0ull | KBTS__FEATURE_FLAG3(rvrn)}}},+ {12, {{0ull | KBTS__FEATURE_FLAG0(frac) | KBTS__FEATURE_FLAG0(numr) | KBTS__FEATURE_FLAG0(dnom) | KBTS__FEATURE_FLAG0(ccmp) | KBTS__FEATURE_FLAG0(clig) | KBTS__FEATURE_FLAG0(calt), 0ull, 0ull | KBTS__FEATURE_FLAG2(ltra) | KBTS__FEATURE_FLAG2(ltrm) | KBTS__FEATURE_FLAG2(locl) | KBTS__FEATURE_FLAG2(rlig) | KBTS__FEATURE_FLAG2(liga) | KBTS__FEATURE_FLAG2(rclt), 0ull}}},+ {7, {{0ull | KBTS__FEATURE_FLAG0(abvm) | KBTS__FEATURE_FLAG0(blwm) | KBTS__FEATURE_FLAG0(curs), 0ull, 0ull | KBTS__FEATURE_FLAG2(mark) | KBTS__FEATURE_FLAG2(mkmk) | KBTS__FEATURE_FLAG2(dist) | KBTS__FEATURE_FLAG2(kern), 0ull}}},+};+static kbts__op_list kbts__OpList_Default = {20, KBTS__ARRAY_LENGTH(kbts__FeatureStages_Default), kbts__FeatureStages_Default, KBTS__ARRAY_LENGTH(kbts__Ops_Default), kbts__Ops_Default};+static kbts__op_kind kbts__Ops_Hangul[] = {+ KBTS__OP_KIND_NORMALIZE,+ KBTS__OP_KIND_NORMALIZE_HANGUL,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES_WITH_USER,+ KBTS__OP_KIND_GPOS_METRICS,+ KBTS__OP_KIND_GPOS_FEATURES,+ KBTS__OP_KIND_POST_GPOS_FIXUP,+};+static kbts__feature_stage kbts__FeatureStages_Hangul[] = {+ {1, {{0ull, 0ull, 0ull, 0ull | KBTS__FEATURE_FLAG3(rvrn)}}},+ {14, {{0ull | KBTS__FEATURE_FLAG0(frac) | KBTS__FEATURE_FLAG0(numr) | KBTS__FEATURE_FLAG0(dnom) | KBTS__FEATURE_FLAG0(ljmo) | KBTS__FEATURE_FLAG0(vjmo) | KBTS__FEATURE_FLAG0(tjmo) | KBTS__FEATURE_FLAG0(ccmp) | KBTS__FEATURE_FLAG0(clig), 0ull, 0ull | KBTS__FEATURE_FLAG2(ltra) | KBTS__FEATURE_FLAG2(ltrm) | KBTS__FEATURE_FLAG2(rlig) | KBTS__FEATURE_FLAG2(liga) | KBTS__FEATURE_FLAG2(locl) | KBTS__FEATURE_FLAG2(rclt), 0ull}}},+ {7, {{0ull | KBTS__FEATURE_FLAG0(abvm) | KBTS__FEATURE_FLAG0(blwm) | KBTS__FEATURE_FLAG0(curs), 0ull, 0ull | KBTS__FEATURE_FLAG2(mkmk) | KBTS__FEATURE_FLAG2(mark) | KBTS__FEATURE_FLAG2(dist) | KBTS__FEATURE_FLAG2(kern), 0ull}}},+};+static kbts__op_list kbts__OpList_Hangul = {22, KBTS__ARRAY_LENGTH(kbts__FeatureStages_Hangul), kbts__FeatureStages_Hangul, KBTS__ARRAY_LENGTH(kbts__Ops_Hangul), kbts__Ops_Hangul};+static kbts__op_kind kbts__Ops_ArabicRclt[] = {+ KBTS__OP_KIND_NORMALIZE,+ KBTS__OP_KIND_FLAG_JOINING_LETTERS,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES_WITH_USER,+ KBTS__OP_KIND_GPOS_METRICS,+ KBTS__OP_KIND_GPOS_FEATURES,+ KBTS__OP_KIND_STCH_POSTPASS,+ KBTS__OP_KIND_POST_GPOS_FIXUP,+};+static kbts__feature_stage kbts__FeatureStages_ArabicRclt[] = {+ {1, {{0ull, 0ull, 0ull, 0ull | KBTS__FEATURE_FLAG3(rvrn)}}},+ {5, {{0ull | KBTS__FEATURE_FLAG0(frac) | KBTS__FEATURE_FLAG0(numr) | KBTS__FEATURE_FLAG0(dnom), 0ull, 0ull, 0ull | KBTS__FEATURE_FLAG3(rtla) | KBTS__FEATURE_FLAG3(rtlm)}}},+ {1, {{0ull, 0ull, 0ull, 0ull | KBTS__FEATURE_FLAG3(stch)}}},+ {2, {{0ull | KBTS__FEATURE_FLAG0(ccmp), 0ull, 0ull | KBTS__FEATURE_FLAG2(locl), 0ull}}},+ {1, {{0ull | KBTS__FEATURE_FLAG0(isol), 0ull, 0ull, 0ull}}},+ {1, {{0ull | KBTS__FEATURE_FLAG0(fina), 0ull, 0ull, 0ull}}},+ {1, {{0ull | KBTS__FEATURE_FLAG0(fin2), 0ull, 0ull, 0ull}}},+ {1, {{0ull | KBTS__FEATURE_FLAG0(fin3), 0ull, 0ull, 0ull}}},+ {1, {{0ull | KBTS__FEATURE_FLAG0(medi), 0ull, 0ull, 0ull}}},+ {1, {{0ull | KBTS__FEATURE_FLAG0(med2), 0ull, 0ull, 0ull}}},+ {1, {{0ull | KBTS__FEATURE_FLAG0(init), 0ull, 0ull, 0ull}}},+ {1, {{0ull, 0ull, 0ull | KBTS__FEATURE_FLAG2(rlig), 0ull}}},+ {5, {{0ull | KBTS__FEATURE_FLAG0(calt) | KBTS__FEATURE_FLAG0(clig), 0ull, 0ull | KBTS__FEATURE_FLAG2(liga) | KBTS__FEATURE_FLAG2(mset) | KBTS__FEATURE_FLAG2(rclt), 0ull}}},+ {7, {{0ull | KBTS__FEATURE_FLAG0(abvm) | KBTS__FEATURE_FLAG0(blwm) | KBTS__FEATURE_FLAG0(curs), 0ull, 0ull | KBTS__FEATURE_FLAG2(mark) | KBTS__FEATURE_FLAG2(mkmk) | KBTS__FEATURE_FLAG2(dist) | KBTS__FEATURE_FLAG2(kern), 0ull}}},+};+static kbts__op_list kbts__OpList_ArabicRclt = {29, KBTS__ARRAY_LENGTH(kbts__FeatureStages_ArabicRclt), kbts__FeatureStages_ArabicRclt, KBTS__ARRAY_LENGTH(kbts__Ops_ArabicRclt), kbts__Ops_ArabicRclt};+static kbts__op_kind kbts__Ops_ArabicNoRclt[] = {+ KBTS__OP_KIND_NORMALIZE,+ KBTS__OP_KIND_FLAG_JOINING_LETTERS,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES_WITH_USER,+ KBTS__OP_KIND_GPOS_METRICS,+ KBTS__OP_KIND_GPOS_FEATURES,+ KBTS__OP_KIND_STCH_POSTPASS,+ KBTS__OP_KIND_POST_GPOS_FIXUP,+};+static kbts__feature_stage kbts__FeatureStages_ArabicNoRclt[] = {+ {1, {{0ull, 0ull, 0ull, 0ull | KBTS__FEATURE_FLAG3(rvrn)}}},+ {5, {{0ull | KBTS__FEATURE_FLAG0(frac) | KBTS__FEATURE_FLAG0(numr) | KBTS__FEATURE_FLAG0(dnom), 0ull, 0ull, 0ull | KBTS__FEATURE_FLAG3(rtla) | KBTS__FEATURE_FLAG3(rtlm)}}},+ {1, {{0ull, 0ull, 0ull, 0ull | KBTS__FEATURE_FLAG3(stch)}}},+ {2, {{0ull | KBTS__FEATURE_FLAG0(ccmp), 0ull, 0ull | KBTS__FEATURE_FLAG2(locl), 0ull}}},+ {1, {{0ull | KBTS__FEATURE_FLAG0(isol), 0ull, 0ull, 0ull}}},+ {1, {{0ull | KBTS__FEATURE_FLAG0(fina), 0ull, 0ull, 0ull}}},+ {1, {{0ull | KBTS__FEATURE_FLAG0(fin2), 0ull, 0ull, 0ull}}},+ {1, {{0ull | KBTS__FEATURE_FLAG0(fin3), 0ull, 0ull, 0ull}}},+ {1, {{0ull | KBTS__FEATURE_FLAG0(medi), 0ull, 0ull, 0ull}}},+ {1, {{0ull | KBTS__FEATURE_FLAG0(med2), 0ull, 0ull, 0ull}}},+ {1, {{0ull | KBTS__FEATURE_FLAG0(init), 0ull, 0ull, 0ull}}},+ {1, {{0ull, 0ull, 0ull | KBTS__FEATURE_FLAG2(rlig), 0ull}}},+ {1, {{0ull | KBTS__FEATURE_FLAG0(calt), 0ull, 0ull, 0ull}}},+ {3, {{0ull | KBTS__FEATURE_FLAG0(clig), 0ull, 0ull | KBTS__FEATURE_FLAG2(liga) | KBTS__FEATURE_FLAG2(mset), 0ull}}},+ {7, {{0ull | KBTS__FEATURE_FLAG0(abvm) | KBTS__FEATURE_FLAG0(blwm) | KBTS__FEATURE_FLAG0(curs), 0ull, 0ull | KBTS__FEATURE_FLAG2(mark) | KBTS__FEATURE_FLAG2(mkmk) | KBTS__FEATURE_FLAG2(dist) | KBTS__FEATURE_FLAG2(kern), 0ull}}},+};+static kbts__op_list kbts__OpList_ArabicNoRclt = {28, KBTS__ARRAY_LENGTH(kbts__FeatureStages_ArabicNoRclt), kbts__FeatureStages_ArabicNoRclt, KBTS__ARRAY_LENGTH(kbts__Ops_ArabicNoRclt), kbts__Ops_ArabicNoRclt};+static kbts__op_kind kbts__Ops_Indic[] = {+ KBTS__OP_KIND_PRE_NORMALIZE_DOTTED_CIRCLES,+ KBTS__OP_KIND_NORMALIZE,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_BEGIN_CLUSTER,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_END_CLUSTER,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_END_SYLLABLE,+ KBTS__OP_KIND_GSUB_FEATURES_WITH_USER,+ KBTS__OP_KIND_GPOS_METRICS,+ KBTS__OP_KIND_GPOS_FEATURES,+ KBTS__OP_KIND_POST_GPOS_FIXUP,+};+static kbts__feature_stage kbts__FeatureStages_Indic[] = {+ {1, {{0ull, 0ull, 0ull, 0ull | KBTS__FEATURE_FLAG3(rvrn)}}},+ {5, {{0ull | KBTS__FEATURE_FLAG0(frac) | KBTS__FEATURE_FLAG0(numr) | KBTS__FEATURE_FLAG0(dnom), 0ull, 0ull | KBTS__FEATURE_FLAG2(ltra) | KBTS__FEATURE_FLAG2(ltrm), 0ull}}},+ {1, {{0ull, 0ull, 0ull | KBTS__FEATURE_FLAG2(nukt), 0ull}}},+ {1, {{0ull | KBTS__FEATURE_FLAG0(akhn), 0ull, 0ull, 0ull}}},+ {1, {{0ull | KBTS__FEATURE_FLAG0(rphf), 0ull, 0ull, 0ull}}},+ {1, {{0ull, 0ull, 0ull | KBTS__FEATURE_FLAG2(rkrf), 0ull}}},+ {1, {{0ull | KBTS__FEATURE_FLAG0(pref), 0ull, 0ull, 0ull}}},+ {1, {{0ull | KBTS__FEATURE_FLAG0(blwf), 0ull, 0ull, 0ull}}},+ {1, {{0ull | KBTS__FEATURE_FLAG0(abvf), 0ull, 0ull, 0ull}}},+ {1, {{0ull | KBTS__FEATURE_FLAG0(half), 0ull, 0ull, 0ull}}},+ {1, {{0ull | KBTS__FEATURE_FLAG0(pstf), 0ull, 0ull, 0ull}}},+ {1, {{0ull, 0ull, 0ull, 0ull | KBTS__FEATURE_FLAG3(vatu)}}},+ {1, {{0ull | KBTS__FEATURE_FLAG0(cjct), 0ull, 0ull, 0ull}}},+ {6, {{0ull | KBTS__FEATURE_FLAG0(abvs) | KBTS__FEATURE_FLAG0(blws) | KBTS__FEATURE_FLAG0(init), 0ull, 0ull | KBTS__FEATURE_FLAG2(haln) | KBTS__FEATURE_FLAG2(pres) | KBTS__FEATURE_FLAG2(psts), 0ull}}},+ {5, {{0ull | KBTS__FEATURE_FLAG0(calt) | KBTS__FEATURE_FLAG0(clig), 0ull, 0ull | KBTS__FEATURE_FLAG2(locl) | KBTS__FEATURE_FLAG2(rlig) | KBTS__FEATURE_FLAG2(rclt), 0ull}}},+ {7, {{0ull | KBTS__FEATURE_FLAG0(abvm) | KBTS__FEATURE_FLAG0(blwm) | KBTS__FEATURE_FLAG0(curs), 0ull, 0ull | KBTS__FEATURE_FLAG2(mark) | KBTS__FEATURE_FLAG2(mkmk) | KBTS__FEATURE_FLAG2(dist) | KBTS__FEATURE_FLAG2(kern), 0ull}}},+};+static kbts__op_list kbts__OpList_Indic = {35, KBTS__ARRAY_LENGTH(kbts__FeatureStages_Indic), kbts__FeatureStages_Indic, KBTS__ARRAY_LENGTH(kbts__Ops_Indic), kbts__Ops_Indic};+static kbts__op_kind kbts__Ops_Khmer[] = {+ KBTS__OP_KIND_PRE_NORMALIZE_DOTTED_CIRCLES,+ KBTS__OP_KIND_NORMALIZE,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_BEGIN_CLUSTER,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_END_CLUSTER,+ KBTS__OP_KIND_END_SYLLABLE,+ KBTS__OP_KIND_GSUB_FEATURES_WITH_USER,+ KBTS__OP_KIND_GPOS_METRICS,+ KBTS__OP_KIND_GPOS_FEATURES,+ KBTS__OP_KIND_POST_GPOS_FIXUP,+};+static kbts__feature_stage kbts__FeatureStages_Khmer[] = {+ {1, {{0ull, 0ull, 0ull, 0ull | KBTS__FEATURE_FLAG3(rvrn)}}},+ {5, {{0ull | KBTS__FEATURE_FLAG0(frac) | KBTS__FEATURE_FLAG0(numr) | KBTS__FEATURE_FLAG0(dnom), 0ull, 0ull | KBTS__FEATURE_FLAG2(ltra) | KBTS__FEATURE_FLAG2(ltrm), 0ull}}},+ {7, {{0ull | KBTS__FEATURE_FLAG0(ccmp) | KBTS__FEATURE_FLAG0(pref) | KBTS__FEATURE_FLAG0(blwf) | KBTS__FEATURE_FLAG0(abvf) | KBTS__FEATURE_FLAG0(pstf) | KBTS__FEATURE_FLAG0(cfar), 0ull, 0ull | KBTS__FEATURE_FLAG2(locl), 0ull}}},+ {8, {{0ull | KBTS__FEATURE_FLAG0(abvs) | KBTS__FEATURE_FLAG0(blws) | KBTS__FEATURE_FLAG0(calt) | KBTS__FEATURE_FLAG0(clig), 0ull, 0ull | KBTS__FEATURE_FLAG2(pres) | KBTS__FEATURE_FLAG2(psts) | KBTS__FEATURE_FLAG2(rclt) | KBTS__FEATURE_FLAG2(rlig), 0ull}}},+ {7, {{0ull | KBTS__FEATURE_FLAG0(abvm) | KBTS__FEATURE_FLAG0(blwm) | KBTS__FEATURE_FLAG0(curs), 0ull, 0ull | KBTS__FEATURE_FLAG2(dist) | KBTS__FEATURE_FLAG2(kern) | KBTS__FEATURE_FLAG2(mark) | KBTS__FEATURE_FLAG2(mkmk), 0ull}}},+};+static kbts__op_list kbts__OpList_Khmer = {28, KBTS__ARRAY_LENGTH(kbts__FeatureStages_Khmer), kbts__FeatureStages_Khmer, KBTS__ARRAY_LENGTH(kbts__Ops_Khmer), kbts__Ops_Khmer};+static kbts__op_kind kbts__Ops_Myanmar[] = {+ KBTS__OP_KIND_PRE_NORMALIZE_DOTTED_CIRCLES,+ KBTS__OP_KIND_NORMALIZE,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_BEGIN_CLUSTER,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_END_CLUSTER,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_END_SYLLABLE,+ KBTS__OP_KIND_GSUB_FEATURES_WITH_USER,+ KBTS__OP_KIND_GPOS_METRICS,+ KBTS__OP_KIND_GPOS_FEATURES,+ KBTS__OP_KIND_POST_GPOS_FIXUP,+};+static kbts__feature_stage kbts__FeatureStages_Myanmar[] = {+ {1, {{0ull, 0ull, 0ull, 0ull | KBTS__FEATURE_FLAG3(rvrn)}}},+ {5, {{0ull | KBTS__FEATURE_FLAG0(frac) | KBTS__FEATURE_FLAG0(numr) | KBTS__FEATURE_FLAG0(dnom), 0ull, 0ull | KBTS__FEATURE_FLAG2(ltra) | KBTS__FEATURE_FLAG2(ltrm), 0ull}}},+ {2, {{0ull | KBTS__FEATURE_FLAG0(ccmp), 0ull, 0ull | KBTS__FEATURE_FLAG2(locl), 0ull}}},+ {1, {{0ull | KBTS__FEATURE_FLAG0(rphf), 0ull, 0ull, 0ull}}},+ {1, {{0ull | KBTS__FEATURE_FLAG0(pref), 0ull, 0ull, 0ull}}},+ {1, {{0ull | KBTS__FEATURE_FLAG0(blwf), 0ull, 0ull, 0ull}}},+ {1, {{0ull | KBTS__FEATURE_FLAG0(pstf), 0ull, 0ull, 0ull}}},+ {9, {{0ull | KBTS__FEATURE_FLAG0(abvs) | KBTS__FEATURE_FLAG0(blws) | KBTS__FEATURE_FLAG0(calt) | KBTS__FEATURE_FLAG0(clig), 0ull, 0ull | KBTS__FEATURE_FLAG2(pres) | KBTS__FEATURE_FLAG2(psts) | KBTS__FEATURE_FLAG2(rlig) | KBTS__FEATURE_FLAG2(liga) | KBTS__FEATURE_FLAG2(rclt), 0ull}}},+ {7, {{0ull | KBTS__FEATURE_FLAG0(abvm) | KBTS__FEATURE_FLAG0(blwm) | KBTS__FEATURE_FLAG0(curs), 0ull, 0ull | KBTS__FEATURE_FLAG2(dist) | KBTS__FEATURE_FLAG2(kern) | KBTS__FEATURE_FLAG2(mark) | KBTS__FEATURE_FLAG2(mkmk), 0ull}}},+};+static kbts__op_list kbts__OpList_Myanmar = {28, KBTS__ARRAY_LENGTH(kbts__FeatureStages_Myanmar), kbts__FeatureStages_Myanmar, KBTS__ARRAY_LENGTH(kbts__Ops_Myanmar), kbts__Ops_Myanmar};+static kbts__op_kind kbts__Ops_Tibetan[] = {+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES_WITH_USER,+ KBTS__OP_KIND_GPOS_METRICS,+ KBTS__OP_KIND_GPOS_FEATURES,+ KBTS__OP_KIND_POST_GPOS_FIXUP,+};+static kbts__feature_stage kbts__FeatureStages_Tibetan[] = {+ {1, {{0ull, 0ull, 0ull | KBTS__FEATURE_FLAG2(locl), 0ull}}},+ {1, {{0ull | KBTS__FEATURE_FLAG0(ccmp), 0ull, 0ull, 0ull}}},+ {4, {{0ull | KBTS__FEATURE_FLAG0(abvs) | KBTS__FEATURE_FLAG0(blws) | KBTS__FEATURE_FLAG0(calt), 0ull, 0ull | KBTS__FEATURE_FLAG2(liga), 0ull}}},+ {4, {{0ull | KBTS__FEATURE_FLAG0(abvm) | KBTS__FEATURE_FLAG0(blwm), 0ull, 0ull | KBTS__FEATURE_FLAG2(kern) | KBTS__FEATURE_FLAG2(mkmk), 0ull}}},+};+static kbts__op_list kbts__OpList_Tibetan = {10, KBTS__ARRAY_LENGTH(kbts__FeatureStages_Tibetan), kbts__FeatureStages_Tibetan, KBTS__ARRAY_LENGTH(kbts__Ops_Tibetan), kbts__Ops_Tibetan};+static kbts__op_kind kbts__Ops_Use[] = {+ KBTS__OP_KIND_PRE_NORMALIZE_DOTTED_CIRCLES,+ KBTS__OP_KIND_NORMALIZE,+ KBTS__OP_KIND_FLAG_JOINING_LETTERS,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_BEGIN_CLUSTER,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_END_CLUSTER,+ KBTS__OP_KIND_END_SYLLABLE,+ KBTS__OP_KIND_GSUB_FEATURES,+ KBTS__OP_KIND_GSUB_FEATURES_WITH_USER,+ KBTS__OP_KIND_GPOS_METRICS,+ KBTS__OP_KIND_GPOS_FEATURES,+ KBTS__OP_KIND_POST_GPOS_FIXUP,+};+static kbts__feature_stage kbts__FeatureStages_Use[] = {+ {1, {{0ull, 0ull, 0ull, 0ull | KBTS__FEATURE_FLAG3(rvrn)}}},+ {5, {{0ull | KBTS__FEATURE_FLAG0(frac) | KBTS__FEATURE_FLAG0(numr) | KBTS__FEATURE_FLAG0(dnom), 0ull, 0ull | KBTS__FEATURE_FLAG2(ltra) | KBTS__FEATURE_FLAG2(ltrm), 0ull}}},+ {4, {{0ull | KBTS__FEATURE_FLAG0(ccmp) | KBTS__FEATURE_FLAG0(akhn), 0ull, 0ull | KBTS__FEATURE_FLAG2(locl) | KBTS__FEATURE_FLAG2(nukt), 0ull}}},+ {1, {{0ull | KBTS__FEATURE_FLAG0(rphf), 0ull, 0ull, 0ull}}},+ {1, {{0ull | KBTS__FEATURE_FLAG0(pref), 0ull, 0ull, 0ull}}},+ {7, {{0ull | KBTS__FEATURE_FLAG0(abvf) | KBTS__FEATURE_FLAG0(blwf) | KBTS__FEATURE_FLAG0(cjct) | KBTS__FEATURE_FLAG0(half) | KBTS__FEATURE_FLAG0(pstf), 0ull, 0ull | KBTS__FEATURE_FLAG2(rkrf), 0ull | KBTS__FEATURE_FLAG3(vatu)}}},+ {4, {{0ull | KBTS__FEATURE_FLAG0(fina) | KBTS__FEATURE_FLAG0(init) | KBTS__FEATURE_FLAG0(isol) | KBTS__FEATURE_FLAG0(medi), 0ull, 0ull, 0ull}}},+ {10, {{0ull | KBTS__FEATURE_FLAG0(abvs) | KBTS__FEATURE_FLAG0(blws) | KBTS__FEATURE_FLAG0(calt) | KBTS__FEATURE_FLAG0(clig), 0ull, 0ull | KBTS__FEATURE_FLAG2(haln) | KBTS__FEATURE_FLAG2(pres) | KBTS__FEATURE_FLAG2(psts) | KBTS__FEATURE_FLAG2(liga) | KBTS__FEATURE_FLAG2(rclt) | KBTS__FEATURE_FLAG2(rlig), 0ull}}},+ {7, {{0ull | KBTS__FEATURE_FLAG0(abvm) | KBTS__FEATURE_FLAG0(blwm) | KBTS__FEATURE_FLAG0(curs), 0ull, 0ull | KBTS__FEATURE_FLAG2(dist) | KBTS__FEATURE_FLAG2(kern) | KBTS__FEATURE_FLAG2(mark) | KBTS__FEATURE_FLAG2(mkmk), 0ull}}},+};+static kbts__op_list kbts__OpList_Use = {40, KBTS__ARRAY_LENGTH(kbts__FeatureStages_Use), kbts__FeatureStages_Use, KBTS__ARRAY_LENGTH(kbts__Ops_Use), kbts__Ops_Use};+#define KBTS__MAXIMUM_DECOMPOSITION_CODEPOINTS 6+typedef struct kbts__script_properties {+ kbts_u32 Tag;+ kbts_shaper Shaper;+} kbts__script_properties;++static kbts__script_properties kbts__ScriptProperties[KBTS_SCRIPT_COUNT] = {+ {KBTS_FOURCC(' ', ' ', ' ', ' '), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('a', 'd', 'l', 'm'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('a', 'h', 'o', 'm'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('h', 'l', 'u', 'w'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('a', 'r', 'a', 'b'), KBTS_SHAPER_ARABIC},+ {KBTS_FOURCC('a', 'r', 'm', 'n'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('a', 'v', 's', 't'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('b', 'a', 'l', 'i'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('b', 'a', 'm', 'u'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('b', 'a', 's', 's'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('b', 'a', 't', 'k'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('b', 'n', 'g', '2'), KBTS_SHAPER_INDIC},+ {KBTS_FOURCC('b', 'h', 'k', 's'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('b', 'o', 'p', 'o'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('b', 'r', 'a', 'h'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('b', 'u', 'g', 'i'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('b', 'u', 'h', 'd'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('c', 'a', 'n', 's'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('c', 'a', 'r', 'i'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('a', 'g', 'h', 'b'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('c', 'a', 'k', 'm'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('c', 'h', 'a', 'm'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('c', 'h', 'e', 'r'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('c', 'h', 'r', 's'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('h', 'a', 'n', 'i'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('c', 'o', 'p', 't'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('c', 'p', 'r', 't'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('c', 'p', 'm', 'n'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('c', 'y', 'r', 'l'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('D', 'F', 'L', 'T'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('D', 'F', 'L', 'T'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('d', 's', 'r', 't'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('d', 'e', 'v', '2'), KBTS_SHAPER_INDIC},+ {KBTS_FOURCC('d', 'i', 'a', 'k'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('d', 'o', 'g', 'r'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('d', 'u', 'p', 'l'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('e', 'g', 'y', 'p'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('e', 'l', 'b', 'a'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('e', 'l', 'y', 'm'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('e', 't', 'h', 'i'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('g', 'a', 'r', 'a'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('g', 'e', 'o', 'r'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('g', 'l', 'a', 'g'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('g', 'o', 't', 'h'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('g', 'r', 'a', 'n'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('g', 'r', 'e', 'k'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('g', 'j', 'r', '2'), KBTS_SHAPER_INDIC},+ {KBTS_FOURCC('g', 'o', 'n', 'g'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('g', 'u', 'r', '2'), KBTS_SHAPER_INDIC},+ {KBTS_FOURCC('g', 'u', 'k', 'h'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('h', 'a', 'n', 'g'), KBTS_SHAPER_HANGUL},+ {KBTS_FOURCC('r', 'o', 'h', 'g'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('h', 'a', 'n', 'o'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('h', 'a', 't', 'r'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('h', 'e', 'b', 'r'), KBTS_SHAPER_HEBREW},+ {KBTS_FOURCC('k', 'a', 'n', 'a'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('a', 'r', 'm', 'i'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('p', 'h', 'l', 'i'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('p', 'r', 't', 'i'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('j', 'a', 'v', 'a'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('k', 't', 'h', 'i'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('k', 'n', 'd', '2'), KBTS_SHAPER_INDIC},+ {KBTS_FOURCC('k', 'a', 'n', 'a'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('k', 'a', 'w', 'i'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('k', 'a', 'l', 'i'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('k', 'h', 'a', 'r'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('k', 'i', 't', 's'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('k', 'h', 'm', 'r'), KBTS_SHAPER_KHMER},+ {KBTS_FOURCC('k', 'h', 'o', 'j'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('s', 'i', 'n', 'd'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('k', 'r', 'a', 'i'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('l', 'a', 'o', ' '), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('l', 'a', 't', 'n'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('l', 'e', 'p', 'c'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('l', 'i', 'm', 'b'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('l', 'i', 'n', 'a'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('l', 'i', 'n', 'b'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('l', 'i', 's', 'u'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('l', 'y', 'c', 'i'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('l', 'y', 'd', 'i'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('m', 'a', 'h', 'j'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('m', 'a', 'k', 'a'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('m', 'l', 'm', '2'), KBTS_SHAPER_INDIC},+ {KBTS_FOURCC('m', 'a', 'n', 'd'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('m', 'a', 'n', 'i'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('m', 'a', 'r', 'c'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('g', 'o', 'n', 'm'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('m', 'e', 'd', 'f'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('m', 't', 'e', 'i'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('m', 'e', 'n', 'd'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('m', 'e', 'r', 'c'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('m', 'e', 'r', 'o'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('p', 'l', 'r', 'd'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('m', 'o', 'd', 'i'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('m', 'o', 'n', 'g'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('m', 'r', 'o', 'o'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('m', 'u', 'l', 't'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('m', 'y', 'm', '2'), KBTS_SHAPER_MYANMAR},+ {KBTS_FOURCC('n', 'b', 'a', 't'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('n', 'a', 'g', 'm'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('n', 'a', 'n', 'd'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('n', 'e', 'w', 'a'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('t', 'a', 'l', 'u'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('n', 'k', 'o', ' '), KBTS_SHAPER_USE},+ {KBTS_FOURCC('n', 's', 'h', 'u'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('h', 'm', 'n', 'p'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('o', 'g', 'a', 'm'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('o', 'l', 'c', 'k'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('o', 'n', 'a', 'o'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('i', 't', 'a', 'l'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('h', 'u', 'n', 'g'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('n', 'a', 'r', 'b'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('p', 'e', 'r', 'm'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('x', 'p', 'e', 'o'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('s', 'o', 'g', 'o'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('s', 'a', 'r', 'b'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('o', 'r', 'k', 'h'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('o', 'u', 'g', 'r'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('o', 'r', 'y', '2'), KBTS_SHAPER_INDIC},+ {KBTS_FOURCC('o', 's', 'g', 'e'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('o', 's', 'm', 'a'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('h', 'm', 'n', 'g'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('p', 'a', 'l', 'm'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('p', 'a', 'u', 'c'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('p', 'h', 'a', 'g'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('p', 'h', 'n', 'x'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('p', 'h', 'l', 'p'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('r', 'j', 'n', 'g'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('r', 'u', 'n', 'r'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('s', 'a', 'm', 'r'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('s', 'a', 'u', 'r'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('s', 'h', 'r', 'd'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('s', 'h', 'a', 'w'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('s', 'i', 'd', 'd'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('s', 'g', 'n', 'w'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('s', 'o', 'g', 'd'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('s', 'i', 'n', 'h'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('s', 'o', 'r', 'a'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('s', 'o', 'y', 'o'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('x', 's', 'u', 'x'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('s', 'u', 'n', 'd'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('s', 'u', 'n', 'u'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('s', 'y', 'l', 'o'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('s', 'y', 'r', 'c'), KBTS_SHAPER_ARABIC},+ {KBTS_FOURCC('t', 'g', 'l', 'g'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('t', 'a', 'g', 'b'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('t', 'a', 'l', 'e'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('l', 'a', 'n', 'a'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('t', 'a', 'v', 't'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('t', 'a', 'k', 'r'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('t', 'm', 'l', '2'), KBTS_SHAPER_INDIC},+ {KBTS_FOURCC('t', 'n', 's', 'a'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('t', 'a', 'n', 'g'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('t', 'e', 'l', '2'), KBTS_SHAPER_INDIC},+ {KBTS_FOURCC('t', 'h', 'a', 'a'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('t', 'h', 'a', 'i'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('t', 'i', 'b', 't'), KBTS_SHAPER_TIBETAN},+ {KBTS_FOURCC('t', 'f', 'n', 'g'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('t', 'i', 'r', 'h'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('t', 'o', 'd', 'r'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('t', 'o', 't', 'o'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('t', 'u', 't', 'g'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('u', 'g', 'a', 'r'), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('v', 'a', 'i', ' '), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('v', 'i', 't', 'h'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('w', 'c', 'h', 'o'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('w', 'a', 'r', 'a'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('y', 'e', 'z', 'i'), KBTS_SHAPER_USE},+ {KBTS_FOURCC('y', 'i', ' ', ' '), KBTS_SHAPER_DEFAULT},+ {KBTS_FOURCC('z', 'a', 'n', 'b'), KBTS_SHAPER_USE},+};++KBTS_EXPORT kbts_script kbts_ScriptTagToScript(kbts_script_tag Tag)+{+ kbts_script Result = 0;+ switch(Tag)+ {+ case KBTS_SCRIPT_TAG_DONT_KNOW: Result = KBTS_SCRIPT_DONT_KNOW; break;+ case KBTS_SCRIPT_TAG_ADLAM: Result = KBTS_SCRIPT_ADLAM; break;+ case KBTS_SCRIPT_TAG_AHOM: Result = KBTS_SCRIPT_AHOM; break;+ case KBTS_SCRIPT_TAG_ANATOLIAN_HIEROGLYPHS: Result = KBTS_SCRIPT_ANATOLIAN_HIEROGLYPHS; break;+ case KBTS_SCRIPT_TAG_ARABIC: Result = KBTS_SCRIPT_ARABIC; break;+ case KBTS_SCRIPT_TAG_ARMENIAN: Result = KBTS_SCRIPT_ARMENIAN; break;+ case KBTS_SCRIPT_TAG_AVESTAN: Result = KBTS_SCRIPT_AVESTAN; break;+ case KBTS_SCRIPT_TAG_BALINESE: Result = KBTS_SCRIPT_BALINESE; break;+ case KBTS_SCRIPT_TAG_BAMUM: Result = KBTS_SCRIPT_BAMUM; break;+ case KBTS_SCRIPT_TAG_BASSA_VAH: Result = KBTS_SCRIPT_BASSA_VAH; break;+ case KBTS_SCRIPT_TAG_BATAK: Result = KBTS_SCRIPT_BATAK; break;+ case KBTS_SCRIPT_TAG_BENGALI: Result = KBTS_SCRIPT_BENGALI; break;+ case KBTS_SCRIPT_TAG_BHAIKSUKI: Result = KBTS_SCRIPT_BHAIKSUKI; break;+ case KBTS_SCRIPT_TAG_BOPOMOFO: Result = KBTS_SCRIPT_BOPOMOFO; break;+ case KBTS_SCRIPT_TAG_BRAHMI: Result = KBTS_SCRIPT_BRAHMI; break;+ case KBTS_SCRIPT_TAG_BUGINESE: Result = KBTS_SCRIPT_BUGINESE; break;+ case KBTS_SCRIPT_TAG_BUHID: Result = KBTS_SCRIPT_BUHID; break;+ case KBTS_SCRIPT_TAG_CANADIAN_SYLLABICS: Result = KBTS_SCRIPT_CANADIAN_SYLLABICS; break;+ case KBTS_SCRIPT_TAG_CARIAN: Result = KBTS_SCRIPT_CARIAN; break;+ case KBTS_SCRIPT_TAG_CAUCASIAN_ALBANIAN: Result = KBTS_SCRIPT_CAUCASIAN_ALBANIAN; break;+ case KBTS_SCRIPT_TAG_CHAKMA: Result = KBTS_SCRIPT_CHAKMA; break;+ case KBTS_SCRIPT_TAG_CHAM: Result = KBTS_SCRIPT_CHAM; break;+ case KBTS_SCRIPT_TAG_CHEROKEE: Result = KBTS_SCRIPT_CHEROKEE; break;+ case KBTS_SCRIPT_TAG_CHORASMIAN: Result = KBTS_SCRIPT_CHORASMIAN; break;+ case KBTS_SCRIPT_TAG_CJK_IDEOGRAPHIC: Result = KBTS_SCRIPT_CJK_IDEOGRAPHIC; break;+ case KBTS_SCRIPT_TAG_COPTIC: Result = KBTS_SCRIPT_COPTIC; break;+ case KBTS_SCRIPT_TAG_CYPRIOT_SYLLABARY: Result = KBTS_SCRIPT_CYPRIOT_SYLLABARY; break;+ case KBTS_SCRIPT_TAG_CYPRO_MINOAN: Result = KBTS_SCRIPT_CYPRO_MINOAN; break;+ case KBTS_SCRIPT_TAG_CYRILLIC: Result = KBTS_SCRIPT_CYRILLIC; break;+ case KBTS_SCRIPT_TAG_DEFAULT: Result = KBTS_SCRIPT_DEFAULT; break;+ case KBTS_SCRIPT_TAG_DESERET: Result = KBTS_SCRIPT_DESERET; break;+ case KBTS_SCRIPT_TAG_DEVANAGARI: Result = KBTS_SCRIPT_DEVANAGARI; break;+ case KBTS_SCRIPT_TAG_DIVES_AKURU: Result = KBTS_SCRIPT_DIVES_AKURU; break;+ case KBTS_SCRIPT_TAG_DOGRA: Result = KBTS_SCRIPT_DOGRA; break;+ case KBTS_SCRIPT_TAG_DUPLOYAN: Result = KBTS_SCRIPT_DUPLOYAN; break;+ case KBTS_SCRIPT_TAG_EGYPTIAN_HIEROGLYPHS: Result = KBTS_SCRIPT_EGYPTIAN_HIEROGLYPHS; break;+ case KBTS_SCRIPT_TAG_ELBASAN: Result = KBTS_SCRIPT_ELBASAN; break;+ case KBTS_SCRIPT_TAG_ELYMAIC: Result = KBTS_SCRIPT_ELYMAIC; break;+ case KBTS_SCRIPT_TAG_ETHIOPIC: Result = KBTS_SCRIPT_ETHIOPIC; break;+ case KBTS_SCRIPT_TAG_GARAY: Result = KBTS_SCRIPT_GARAY; break;+ case KBTS_SCRIPT_TAG_GEORGIAN: Result = KBTS_SCRIPT_GEORGIAN; break;+ case KBTS_SCRIPT_TAG_GLAGOLITIC: Result = KBTS_SCRIPT_GLAGOLITIC; break;+ case KBTS_SCRIPT_TAG_GOTHIC: Result = KBTS_SCRIPT_GOTHIC; break;+ case KBTS_SCRIPT_TAG_GRANTHA: Result = KBTS_SCRIPT_GRANTHA; break;+ case KBTS_SCRIPT_TAG_GREEK: Result = KBTS_SCRIPT_GREEK; break;+ case KBTS_SCRIPT_TAG_GUJARATI: Result = KBTS_SCRIPT_GUJARATI; break;+ case KBTS_SCRIPT_TAG_GUNJALA_GONDI: Result = KBTS_SCRIPT_GUNJALA_GONDI; break;+ case KBTS_SCRIPT_TAG_GURMUKHI: Result = KBTS_SCRIPT_GURMUKHI; break;+ case KBTS_SCRIPT_TAG_GURUNG_KHEMA: Result = KBTS_SCRIPT_GURUNG_KHEMA; break;+ case KBTS_SCRIPT_TAG_HANGUL: Result = KBTS_SCRIPT_HANGUL; break;+ case KBTS_SCRIPT_TAG_HANIFI_ROHINGYA: Result = KBTS_SCRIPT_HANIFI_ROHINGYA; break;+ case KBTS_SCRIPT_TAG_HANUNOO: Result = KBTS_SCRIPT_HANUNOO; break;+ case KBTS_SCRIPT_TAG_HATRAN: Result = KBTS_SCRIPT_HATRAN; break;+ case KBTS_SCRIPT_TAG_HEBREW: Result = KBTS_SCRIPT_HEBREW; break;+ case KBTS_SCRIPT_TAG_HIRAGANA: Result = KBTS_SCRIPT_HIRAGANA; break;+ case KBTS_SCRIPT_TAG_IMPERIAL_ARAMAIC: Result = KBTS_SCRIPT_IMPERIAL_ARAMAIC; break;+ case KBTS_SCRIPT_TAG_INSCRIPTIONAL_PAHLAVI: Result = KBTS_SCRIPT_INSCRIPTIONAL_PAHLAVI; break;+ case KBTS_SCRIPT_TAG_INSCRIPTIONAL_PARTHIAN: Result = KBTS_SCRIPT_INSCRIPTIONAL_PARTHIAN; break;+ case KBTS_SCRIPT_TAG_JAVANESE: Result = KBTS_SCRIPT_JAVANESE; break;+ case KBTS_SCRIPT_TAG_KAITHI: Result = KBTS_SCRIPT_KAITHI; break;+ case KBTS_SCRIPT_TAG_KANNADA: Result = KBTS_SCRIPT_KANNADA; break;+ case KBTS_SCRIPT_TAG_KAWI: Result = KBTS_SCRIPT_KAWI; break;+ case KBTS_SCRIPT_TAG_KAYAH_LI: Result = KBTS_SCRIPT_KAYAH_LI; break;+ case KBTS_SCRIPT_TAG_KHAROSHTHI: Result = KBTS_SCRIPT_KHAROSHTHI; break;+ case KBTS_SCRIPT_TAG_KHITAN_SMALL_SCRIPT: Result = KBTS_SCRIPT_KHITAN_SMALL_SCRIPT; break;+ case KBTS_SCRIPT_TAG_KHMER: Result = KBTS_SCRIPT_KHMER; break;+ case KBTS_SCRIPT_TAG_KHOJKI: Result = KBTS_SCRIPT_KHOJKI; break;+ case KBTS_SCRIPT_TAG_KHUDAWADI: Result = KBTS_SCRIPT_KHUDAWADI; break;+ case KBTS_SCRIPT_TAG_KIRAT_RAI: Result = KBTS_SCRIPT_KIRAT_RAI; break;+ case KBTS_SCRIPT_TAG_LAO: Result = KBTS_SCRIPT_LAO; break;+ case KBTS_SCRIPT_TAG_LATIN: Result = KBTS_SCRIPT_LATIN; break;+ case KBTS_SCRIPT_TAG_LEPCHA: Result = KBTS_SCRIPT_LEPCHA; break;+ case KBTS_SCRIPT_TAG_LIMBU: Result = KBTS_SCRIPT_LIMBU; break;+ case KBTS_SCRIPT_TAG_LINEAR_A: Result = KBTS_SCRIPT_LINEAR_A; break;+ case KBTS_SCRIPT_TAG_LINEAR_B: Result = KBTS_SCRIPT_LINEAR_B; break;+ case KBTS_SCRIPT_TAG_LISU: Result = KBTS_SCRIPT_LISU; break;+ case KBTS_SCRIPT_TAG_LYCIAN: Result = KBTS_SCRIPT_LYCIAN; break;+ case KBTS_SCRIPT_TAG_LYDIAN: Result = KBTS_SCRIPT_LYDIAN; break;+ case KBTS_SCRIPT_TAG_MAHAJANI: Result = KBTS_SCRIPT_MAHAJANI; break;+ case KBTS_SCRIPT_TAG_MAKASAR: Result = KBTS_SCRIPT_MAKASAR; break;+ case KBTS_SCRIPT_TAG_MALAYALAM: Result = KBTS_SCRIPT_MALAYALAM; break;+ case KBTS_SCRIPT_TAG_MANDAIC: Result = KBTS_SCRIPT_MANDAIC; break;+ case KBTS_SCRIPT_TAG_MANICHAEAN: Result = KBTS_SCRIPT_MANICHAEAN; break;+ case KBTS_SCRIPT_TAG_MARCHEN: Result = KBTS_SCRIPT_MARCHEN; break;+ case KBTS_SCRIPT_TAG_MASARAM_GONDI: Result = KBTS_SCRIPT_MASARAM_GONDI; break;+ case KBTS_SCRIPT_TAG_MEDEFAIDRIN: Result = KBTS_SCRIPT_MEDEFAIDRIN; break;+ case KBTS_SCRIPT_TAG_MEETEI_MAYEK: Result = KBTS_SCRIPT_MEETEI_MAYEK; break;+ case KBTS_SCRIPT_TAG_MENDE_KIKAKUI: Result = KBTS_SCRIPT_MENDE_KIKAKUI; break;+ case KBTS_SCRIPT_TAG_MEROITIC_CURSIVE: Result = KBTS_SCRIPT_MEROITIC_CURSIVE; break;+ case KBTS_SCRIPT_TAG_MEROITIC_HIEROGLYPHS: Result = KBTS_SCRIPT_MEROITIC_HIEROGLYPHS; break;+ case KBTS_SCRIPT_TAG_MIAO: Result = KBTS_SCRIPT_MIAO; break;+ case KBTS_SCRIPT_TAG_MODI: Result = KBTS_SCRIPT_MODI; break;+ case KBTS_SCRIPT_TAG_MONGOLIAN: Result = KBTS_SCRIPT_MONGOLIAN; break;+ case KBTS_SCRIPT_TAG_MRO: Result = KBTS_SCRIPT_MRO; break;+ case KBTS_SCRIPT_TAG_MULTANI: Result = KBTS_SCRIPT_MULTANI; break;+ case KBTS_SCRIPT_TAG_MYANMAR: Result = KBTS_SCRIPT_MYANMAR; break;+ case KBTS_SCRIPT_TAG_NABATAEAN: Result = KBTS_SCRIPT_NABATAEAN; break;+ case KBTS_SCRIPT_TAG_NAG_MUNDARI: Result = KBTS_SCRIPT_NAG_MUNDARI; break;+ case KBTS_SCRIPT_TAG_NANDINAGARI: Result = KBTS_SCRIPT_NANDINAGARI; break;+ case KBTS_SCRIPT_TAG_NEWA: Result = KBTS_SCRIPT_NEWA; break;+ case KBTS_SCRIPT_TAG_NEW_TAI_LUE: Result = KBTS_SCRIPT_NEW_TAI_LUE; break;+ case KBTS_SCRIPT_TAG_NKO: Result = KBTS_SCRIPT_NKO; break;+ case KBTS_SCRIPT_TAG_NUSHU: Result = KBTS_SCRIPT_NUSHU; break;+ case KBTS_SCRIPT_TAG_NYIAKENG_PUACHUE_HMONG: Result = KBTS_SCRIPT_NYIAKENG_PUACHUE_HMONG; break;+ case KBTS_SCRIPT_TAG_OGHAM: Result = KBTS_SCRIPT_OGHAM; break;+ case KBTS_SCRIPT_TAG_OL_CHIKI: Result = KBTS_SCRIPT_OL_CHIKI; break;+ case KBTS_SCRIPT_TAG_OL_ONAL: Result = KBTS_SCRIPT_OL_ONAL; break;+ case KBTS_SCRIPT_TAG_OLD_ITALIC: Result = KBTS_SCRIPT_OLD_ITALIC; break;+ case KBTS_SCRIPT_TAG_OLD_HUNGARIAN: Result = KBTS_SCRIPT_OLD_HUNGARIAN; break;+ case KBTS_SCRIPT_TAG_OLD_NORTH_ARABIAN: Result = KBTS_SCRIPT_OLD_NORTH_ARABIAN; break;+ case KBTS_SCRIPT_TAG_OLD_PERMIC: Result = KBTS_SCRIPT_OLD_PERMIC; break;+ case KBTS_SCRIPT_TAG_OLD_PERSIAN_CUNEIFORM: Result = KBTS_SCRIPT_OLD_PERSIAN_CUNEIFORM; break;+ case KBTS_SCRIPT_TAG_OLD_SOGDIAN: Result = KBTS_SCRIPT_OLD_SOGDIAN; break;+ case KBTS_SCRIPT_TAG_OLD_SOUTH_ARABIAN: Result = KBTS_SCRIPT_OLD_SOUTH_ARABIAN; break;+ case KBTS_SCRIPT_TAG_OLD_TURKIC: Result = KBTS_SCRIPT_OLD_TURKIC; break;+ case KBTS_SCRIPT_TAG_OLD_UYGHUR: Result = KBTS_SCRIPT_OLD_UYGHUR; break;+ case KBTS_SCRIPT_TAG_ODIA: Result = KBTS_SCRIPT_ODIA; break;+ case KBTS_SCRIPT_TAG_OSAGE: Result = KBTS_SCRIPT_OSAGE; break;+ case KBTS_SCRIPT_TAG_OSMANYA: Result = KBTS_SCRIPT_OSMANYA; break;+ case KBTS_SCRIPT_TAG_PAHAWH_HMONG: Result = KBTS_SCRIPT_PAHAWH_HMONG; break;+ case KBTS_SCRIPT_TAG_PALMYRENE: Result = KBTS_SCRIPT_PALMYRENE; break;+ case KBTS_SCRIPT_TAG_PAU_CIN_HAU: Result = KBTS_SCRIPT_PAU_CIN_HAU; break;+ case KBTS_SCRIPT_TAG_PHAGS_PA: Result = KBTS_SCRIPT_PHAGS_PA; break;+ case KBTS_SCRIPT_TAG_PHOENICIAN: Result = KBTS_SCRIPT_PHOENICIAN; break;+ case KBTS_SCRIPT_TAG_PSALTER_PAHLAVI: Result = KBTS_SCRIPT_PSALTER_PAHLAVI; break;+ case KBTS_SCRIPT_TAG_REJANG: Result = KBTS_SCRIPT_REJANG; break;+ case KBTS_SCRIPT_TAG_RUNIC: Result = KBTS_SCRIPT_RUNIC; break;+ case KBTS_SCRIPT_TAG_SAMARITAN: Result = KBTS_SCRIPT_SAMARITAN; break;+ case KBTS_SCRIPT_TAG_SAURASHTRA: Result = KBTS_SCRIPT_SAURASHTRA; break;+ case KBTS_SCRIPT_TAG_SHARADA: Result = KBTS_SCRIPT_SHARADA; break;+ case KBTS_SCRIPT_TAG_SHAVIAN: Result = KBTS_SCRIPT_SHAVIAN; break;+ case KBTS_SCRIPT_TAG_SIDDHAM: Result = KBTS_SCRIPT_SIDDHAM; break;+ case KBTS_SCRIPT_TAG_SIGN_WRITING: Result = KBTS_SCRIPT_SIGN_WRITING; break;+ case KBTS_SCRIPT_TAG_SOGDIAN: Result = KBTS_SCRIPT_SOGDIAN; break;+ case KBTS_SCRIPT_TAG_SINHALA: Result = KBTS_SCRIPT_SINHALA; break;+ case KBTS_SCRIPT_TAG_SORA_SOMPENG: Result = KBTS_SCRIPT_SORA_SOMPENG; break;+ case KBTS_SCRIPT_TAG_SOYOMBO: Result = KBTS_SCRIPT_SOYOMBO; break;+ case KBTS_SCRIPT_TAG_SUMERO_AKKADIAN_CUNEIFORM: Result = KBTS_SCRIPT_SUMERO_AKKADIAN_CUNEIFORM; break;+ case KBTS_SCRIPT_TAG_SUNDANESE: Result = KBTS_SCRIPT_SUNDANESE; break;+ case KBTS_SCRIPT_TAG_SUNUWAR: Result = KBTS_SCRIPT_SUNUWAR; break;+ case KBTS_SCRIPT_TAG_SYLOTI_NAGRI: Result = KBTS_SCRIPT_SYLOTI_NAGRI; break;+ case KBTS_SCRIPT_TAG_SYRIAC: Result = KBTS_SCRIPT_SYRIAC; break;+ case KBTS_SCRIPT_TAG_TAGALOG: Result = KBTS_SCRIPT_TAGALOG; break;+ case KBTS_SCRIPT_TAG_TAGBANWA: Result = KBTS_SCRIPT_TAGBANWA; break;+ case KBTS_SCRIPT_TAG_TAI_LE: Result = KBTS_SCRIPT_TAI_LE; break;+ case KBTS_SCRIPT_TAG_TAI_THAM: Result = KBTS_SCRIPT_TAI_THAM; break;+ case KBTS_SCRIPT_TAG_TAI_VIET: Result = KBTS_SCRIPT_TAI_VIET; break;+ case KBTS_SCRIPT_TAG_TAKRI: Result = KBTS_SCRIPT_TAKRI; break;+ case KBTS_SCRIPT_TAG_TAMIL: Result = KBTS_SCRIPT_TAMIL; break;+ case KBTS_SCRIPT_TAG_TANGSA: Result = KBTS_SCRIPT_TANGSA; break;+ case KBTS_SCRIPT_TAG_TANGUT: Result = KBTS_SCRIPT_TANGUT; break;+ case KBTS_SCRIPT_TAG_TELUGU: Result = KBTS_SCRIPT_TELUGU; break;+ case KBTS_SCRIPT_TAG_THAANA: Result = KBTS_SCRIPT_THAANA; break;+ case KBTS_SCRIPT_TAG_THAI: Result = KBTS_SCRIPT_THAI; break;+ case KBTS_SCRIPT_TAG_TIBETAN: Result = KBTS_SCRIPT_TIBETAN; break;+ case KBTS_SCRIPT_TAG_TIFINAGH: Result = KBTS_SCRIPT_TIFINAGH; break;+ case KBTS_SCRIPT_TAG_TIRHUTA: Result = KBTS_SCRIPT_TIRHUTA; break;+ case KBTS_SCRIPT_TAG_TODHRI: Result = KBTS_SCRIPT_TODHRI; break;+ case KBTS_SCRIPT_TAG_TOTO: Result = KBTS_SCRIPT_TOTO; break;+ case KBTS_SCRIPT_TAG_TULU_TIGALARI: Result = KBTS_SCRIPT_TULU_TIGALARI; break;+ case KBTS_SCRIPT_TAG_UGARITIC_CUNEIFORM: Result = KBTS_SCRIPT_UGARITIC_CUNEIFORM; break;+ case KBTS_SCRIPT_TAG_VAI: Result = KBTS_SCRIPT_VAI; break;+ case KBTS_SCRIPT_TAG_VITHKUQI: Result = KBTS_SCRIPT_VITHKUQI; break;+ case KBTS_SCRIPT_TAG_WANCHO: Result = KBTS_SCRIPT_WANCHO; break;+ case KBTS_SCRIPT_TAG_WARANG_CITI: Result = KBTS_SCRIPT_WARANG_CITI; break;+ case KBTS_SCRIPT_TAG_YEZIDI: Result = KBTS_SCRIPT_YEZIDI; break;+ case KBTS_SCRIPT_TAG_YI: Result = KBTS_SCRIPT_YI; break;+ case KBTS_SCRIPT_TAG_ZANABAZAR_SQUARE: Result = KBTS_SCRIPT_ZANABAZAR_SQUARE; break;+ default: break;+ }+ return Result;+}++static kbts__feature_id kbts__FeatureTagToId(kbts_feature_tag Tag)+{+ kbts__feature_id Result = 0;+ switch(Tag)+ {+ case KBTS_FEATURE_TAG_isol: Result = KBTS__FEATURE_ID_isol; break;+ case KBTS_FEATURE_TAG_fina: Result = KBTS__FEATURE_ID_fina; break;+ case KBTS_FEATURE_TAG_fin2: Result = KBTS__FEATURE_ID_fin2; break;+ case KBTS_FEATURE_TAG_fin3: Result = KBTS__FEATURE_ID_fin3; break;+ case KBTS_FEATURE_TAG_medi: Result = KBTS__FEATURE_ID_medi; break;+ case KBTS_FEATURE_TAG_med2: Result = KBTS__FEATURE_ID_med2; break;+ case KBTS_FEATURE_TAG_init: Result = KBTS__FEATURE_ID_init; break;+ case KBTS_FEATURE_TAG_ljmo: Result = KBTS__FEATURE_ID_ljmo; break;+ case KBTS_FEATURE_TAG_vjmo: Result = KBTS__FEATURE_ID_vjmo; break;+ case KBTS_FEATURE_TAG_tjmo: Result = KBTS__FEATURE_ID_tjmo; break;+ case KBTS_FEATURE_TAG_rphf: Result = KBTS__FEATURE_ID_rphf; break;+ case KBTS_FEATURE_TAG_blwf: Result = KBTS__FEATURE_ID_blwf; break;+ case KBTS_FEATURE_TAG_half: Result = KBTS__FEATURE_ID_half; break;+ case KBTS_FEATURE_TAG_pstf: Result = KBTS__FEATURE_ID_pstf; break;+ case KBTS_FEATURE_TAG_abvf: Result = KBTS__FEATURE_ID_abvf; break;+ case KBTS_FEATURE_TAG_pref: Result = KBTS__FEATURE_ID_pref; break;+ case KBTS_FEATURE_TAG_numr: Result = KBTS__FEATURE_ID_numr; break;+ case KBTS_FEATURE_TAG_frac: Result = KBTS__FEATURE_ID_frac; break;+ case KBTS_FEATURE_TAG_dnom: Result = KBTS__FEATURE_ID_dnom; break;+ case KBTS_FEATURE_TAG_cfar: Result = KBTS__FEATURE_ID_cfar; break;+ case KBTS_FEATURE_TAG_aalt: Result = KBTS__FEATURE_ID_aalt; break;+ case KBTS_FEATURE_TAG_abvm: Result = KBTS__FEATURE_ID_abvm; break;+ case KBTS_FEATURE_TAG_abvs: Result = KBTS__FEATURE_ID_abvs; break;+ case KBTS_FEATURE_TAG_afrc: Result = KBTS__FEATURE_ID_afrc; break;+ case KBTS_FEATURE_TAG_akhn: Result = KBTS__FEATURE_ID_akhn; break;+ case KBTS_FEATURE_TAG_apkn: Result = KBTS__FEATURE_ID_apkn; break;+ case KBTS_FEATURE_TAG_blwm: Result = KBTS__FEATURE_ID_blwm; break;+ case KBTS_FEATURE_TAG_blws: Result = KBTS__FEATURE_ID_blws; break;+ case KBTS_FEATURE_TAG_calt: Result = KBTS__FEATURE_ID_calt; break;+ case KBTS_FEATURE_TAG_case: Result = KBTS__FEATURE_ID_case; break;+ case KBTS_FEATURE_TAG_ccmp: Result = KBTS__FEATURE_ID_ccmp; break;+ case KBTS_FEATURE_TAG_chws: Result = KBTS__FEATURE_ID_chws; break;+ case KBTS_FEATURE_TAG_cjct: Result = KBTS__FEATURE_ID_cjct; break;+ case KBTS_FEATURE_TAG_clig: Result = KBTS__FEATURE_ID_clig; break;+ case KBTS_FEATURE_TAG_cpct: Result = KBTS__FEATURE_ID_cpct; break;+ case KBTS_FEATURE_TAG_cpsp: Result = KBTS__FEATURE_ID_cpsp; break;+ case KBTS_FEATURE_TAG_cswh: Result = KBTS__FEATURE_ID_cswh; break;+ case KBTS_FEATURE_TAG_curs: Result = KBTS__FEATURE_ID_curs; break;+ case KBTS_FEATURE_TAG_cv01: Result = KBTS__FEATURE_ID_cv01; break;+ case KBTS_FEATURE_TAG_cv02: Result = KBTS__FEATURE_ID_cv02; break;+ case KBTS_FEATURE_TAG_cv03: Result = KBTS__FEATURE_ID_cv03; break;+ case KBTS_FEATURE_TAG_cv04: Result = KBTS__FEATURE_ID_cv04; break;+ case KBTS_FEATURE_TAG_cv05: Result = KBTS__FEATURE_ID_cv05; break;+ case KBTS_FEATURE_TAG_cv06: Result = KBTS__FEATURE_ID_cv06; break;+ case KBTS_FEATURE_TAG_cv07: Result = KBTS__FEATURE_ID_cv07; break;+ case KBTS_FEATURE_TAG_cv08: Result = KBTS__FEATURE_ID_cv08; break;+ case KBTS_FEATURE_TAG_cv09: Result = KBTS__FEATURE_ID_cv09; break;+ case KBTS_FEATURE_TAG_cv10: Result = KBTS__FEATURE_ID_cv10; break;+ case KBTS_FEATURE_TAG_cv11: Result = KBTS__FEATURE_ID_cv11; break;+ case KBTS_FEATURE_TAG_cv12: Result = KBTS__FEATURE_ID_cv12; break;+ case KBTS_FEATURE_TAG_cv13: Result = KBTS__FEATURE_ID_cv13; break;+ case KBTS_FEATURE_TAG_cv14: Result = KBTS__FEATURE_ID_cv14; break;+ case KBTS_FEATURE_TAG_cv15: Result = KBTS__FEATURE_ID_cv15; break;+ case KBTS_FEATURE_TAG_cv16: Result = KBTS__FEATURE_ID_cv16; break;+ case KBTS_FEATURE_TAG_cv17: Result = KBTS__FEATURE_ID_cv17; break;+ case KBTS_FEATURE_TAG_cv18: Result = KBTS__FEATURE_ID_cv18; break;+ case KBTS_FEATURE_TAG_cv19: Result = KBTS__FEATURE_ID_cv19; break;+ case KBTS_FEATURE_TAG_cv20: Result = KBTS__FEATURE_ID_cv20; break;+ case KBTS_FEATURE_TAG_cv21: Result = KBTS__FEATURE_ID_cv21; break;+ case KBTS_FEATURE_TAG_cv22: Result = KBTS__FEATURE_ID_cv22; break;+ case KBTS_FEATURE_TAG_cv23: Result = KBTS__FEATURE_ID_cv23; break;+ case KBTS_FEATURE_TAG_cv24: Result = KBTS__FEATURE_ID_cv24; break;+ case KBTS_FEATURE_TAG_cv25: Result = KBTS__FEATURE_ID_cv25; break;+ case KBTS_FEATURE_TAG_cv26: Result = KBTS__FEATURE_ID_cv26; break;+ case KBTS_FEATURE_TAG_cv27: Result = KBTS__FEATURE_ID_cv27; break;+ case KBTS_FEATURE_TAG_cv28: Result = KBTS__FEATURE_ID_cv28; break;+ case KBTS_FEATURE_TAG_cv29: Result = KBTS__FEATURE_ID_cv29; break;+ case KBTS_FEATURE_TAG_cv30: Result = KBTS__FEATURE_ID_cv30; break;+ case KBTS_FEATURE_TAG_cv31: Result = KBTS__FEATURE_ID_cv31; break;+ case KBTS_FEATURE_TAG_cv32: Result = KBTS__FEATURE_ID_cv32; break;+ case KBTS_FEATURE_TAG_cv33: Result = KBTS__FEATURE_ID_cv33; break;+ case KBTS_FEATURE_TAG_cv34: Result = KBTS__FEATURE_ID_cv34; break;+ case KBTS_FEATURE_TAG_cv35: Result = KBTS__FEATURE_ID_cv35; break;+ case KBTS_FEATURE_TAG_cv36: Result = KBTS__FEATURE_ID_cv36; break;+ case KBTS_FEATURE_TAG_cv37: Result = KBTS__FEATURE_ID_cv37; break;+ case KBTS_FEATURE_TAG_cv38: Result = KBTS__FEATURE_ID_cv38; break;+ case KBTS_FEATURE_TAG_cv39: Result = KBTS__FEATURE_ID_cv39; break;+ case KBTS_FEATURE_TAG_cv40: Result = KBTS__FEATURE_ID_cv40; break;+ case KBTS_FEATURE_TAG_cv41: Result = KBTS__FEATURE_ID_cv41; break;+ case KBTS_FEATURE_TAG_cv42: Result = KBTS__FEATURE_ID_cv42; break;+ case KBTS_FEATURE_TAG_cv43: Result = KBTS__FEATURE_ID_cv43; break;+ case KBTS_FEATURE_TAG_cv44: Result = KBTS__FEATURE_ID_cv44; break;+ case KBTS_FEATURE_TAG_cv45: Result = KBTS__FEATURE_ID_cv45; break;+ case KBTS_FEATURE_TAG_cv46: Result = KBTS__FEATURE_ID_cv46; break;+ case KBTS_FEATURE_TAG_cv47: Result = KBTS__FEATURE_ID_cv47; break;+ case KBTS_FEATURE_TAG_cv48: Result = KBTS__FEATURE_ID_cv48; break;+ case KBTS_FEATURE_TAG_cv49: Result = KBTS__FEATURE_ID_cv49; break;+ case KBTS_FEATURE_TAG_cv50: Result = KBTS__FEATURE_ID_cv50; break;+ case KBTS_FEATURE_TAG_cv51: Result = KBTS__FEATURE_ID_cv51; break;+ case KBTS_FEATURE_TAG_cv52: Result = KBTS__FEATURE_ID_cv52; break;+ case KBTS_FEATURE_TAG_cv53: Result = KBTS__FEATURE_ID_cv53; break;+ case KBTS_FEATURE_TAG_cv54: Result = KBTS__FEATURE_ID_cv54; break;+ case KBTS_FEATURE_TAG_cv55: Result = KBTS__FEATURE_ID_cv55; break;+ case KBTS_FEATURE_TAG_cv56: Result = KBTS__FEATURE_ID_cv56; break;+ case KBTS_FEATURE_TAG_cv57: Result = KBTS__FEATURE_ID_cv57; break;+ case KBTS_FEATURE_TAG_cv58: Result = KBTS__FEATURE_ID_cv58; break;+ case KBTS_FEATURE_TAG_cv59: Result = KBTS__FEATURE_ID_cv59; break;+ case KBTS_FEATURE_TAG_cv60: Result = KBTS__FEATURE_ID_cv60; break;+ case KBTS_FEATURE_TAG_cv61: Result = KBTS__FEATURE_ID_cv61; break;+ case KBTS_FEATURE_TAG_cv62: Result = KBTS__FEATURE_ID_cv62; break;+ case KBTS_FEATURE_TAG_cv63: Result = KBTS__FEATURE_ID_cv63; break;+ case KBTS_FEATURE_TAG_cv64: Result = KBTS__FEATURE_ID_cv64; break;+ case KBTS_FEATURE_TAG_cv65: Result = KBTS__FEATURE_ID_cv65; break;+ case KBTS_FEATURE_TAG_cv66: Result = KBTS__FEATURE_ID_cv66; break;+ case KBTS_FEATURE_TAG_cv67: Result = KBTS__FEATURE_ID_cv67; break;+ case KBTS_FEATURE_TAG_cv68: Result = KBTS__FEATURE_ID_cv68; break;+ case KBTS_FEATURE_TAG_cv69: Result = KBTS__FEATURE_ID_cv69; break;+ case KBTS_FEATURE_TAG_cv70: Result = KBTS__FEATURE_ID_cv70; break;+ case KBTS_FEATURE_TAG_cv71: Result = KBTS__FEATURE_ID_cv71; break;+ case KBTS_FEATURE_TAG_cv72: Result = KBTS__FEATURE_ID_cv72; break;+ case KBTS_FEATURE_TAG_cv73: Result = KBTS__FEATURE_ID_cv73; break;+ case KBTS_FEATURE_TAG_cv74: Result = KBTS__FEATURE_ID_cv74; break;+ case KBTS_FEATURE_TAG_cv75: Result = KBTS__FEATURE_ID_cv75; break;+ case KBTS_FEATURE_TAG_cv76: Result = KBTS__FEATURE_ID_cv76; break;+ case KBTS_FEATURE_TAG_cv77: Result = KBTS__FEATURE_ID_cv77; break;+ case KBTS_FEATURE_TAG_cv78: Result = KBTS__FEATURE_ID_cv78; break;+ case KBTS_FEATURE_TAG_cv79: Result = KBTS__FEATURE_ID_cv79; break;+ case KBTS_FEATURE_TAG_cv80: Result = KBTS__FEATURE_ID_cv80; break;+ case KBTS_FEATURE_TAG_cv81: Result = KBTS__FEATURE_ID_cv81; break;+ case KBTS_FEATURE_TAG_cv82: Result = KBTS__FEATURE_ID_cv82; break;+ case KBTS_FEATURE_TAG_cv83: Result = KBTS__FEATURE_ID_cv83; break;+ case KBTS_FEATURE_TAG_cv84: Result = KBTS__FEATURE_ID_cv84; break;+ case KBTS_FEATURE_TAG_cv85: Result = KBTS__FEATURE_ID_cv85; break;+ case KBTS_FEATURE_TAG_cv86: Result = KBTS__FEATURE_ID_cv86; break;+ case KBTS_FEATURE_TAG_cv87: Result = KBTS__FEATURE_ID_cv87; break;+ case KBTS_FEATURE_TAG_cv88: Result = KBTS__FEATURE_ID_cv88; break;+ case KBTS_FEATURE_TAG_cv89: Result = KBTS__FEATURE_ID_cv89; break;+ case KBTS_FEATURE_TAG_cv90: Result = KBTS__FEATURE_ID_cv90; break;+ case KBTS_FEATURE_TAG_cv91: Result = KBTS__FEATURE_ID_cv91; break;+ case KBTS_FEATURE_TAG_cv92: Result = KBTS__FEATURE_ID_cv92; break;+ case KBTS_FEATURE_TAG_cv93: Result = KBTS__FEATURE_ID_cv93; break;+ case KBTS_FEATURE_TAG_cv94: Result = KBTS__FEATURE_ID_cv94; break;+ case KBTS_FEATURE_TAG_cv95: Result = KBTS__FEATURE_ID_cv95; break;+ case KBTS_FEATURE_TAG_cv96: Result = KBTS__FEATURE_ID_cv96; break;+ case KBTS_FEATURE_TAG_cv97: Result = KBTS__FEATURE_ID_cv97; break;+ case KBTS_FEATURE_TAG_cv98: Result = KBTS__FEATURE_ID_cv98; break;+ case KBTS_FEATURE_TAG_cv99: Result = KBTS__FEATURE_ID_cv99; break;+ case KBTS_FEATURE_TAG_c2pc: Result = KBTS__FEATURE_ID_c2pc; break;+ case KBTS_FEATURE_TAG_c2sc: Result = KBTS__FEATURE_ID_c2sc; break;+ case KBTS_FEATURE_TAG_dist: Result = KBTS__FEATURE_ID_dist; break;+ case KBTS_FEATURE_TAG_dlig: Result = KBTS__FEATURE_ID_dlig; break;+ case KBTS_FEATURE_TAG_dtls: Result = KBTS__FEATURE_ID_dtls; break;+ case KBTS_FEATURE_TAG_expt: Result = KBTS__FEATURE_ID_expt; break;+ case KBTS_FEATURE_TAG_falt: Result = KBTS__FEATURE_ID_falt; break;+ case KBTS_FEATURE_TAG_flac: Result = KBTS__FEATURE_ID_flac; break;+ case KBTS_FEATURE_TAG_fwid: Result = KBTS__FEATURE_ID_fwid; break;+ case KBTS_FEATURE_TAG_haln: Result = KBTS__FEATURE_ID_haln; break;+ case KBTS_FEATURE_TAG_halt: Result = KBTS__FEATURE_ID_halt; break;+ case KBTS_FEATURE_TAG_hist: Result = KBTS__FEATURE_ID_hist; break;+ case KBTS_FEATURE_TAG_hkna: Result = KBTS__FEATURE_ID_hkna; break;+ case KBTS_FEATURE_TAG_hlig: Result = KBTS__FEATURE_ID_hlig; break;+ case KBTS_FEATURE_TAG_hngl: Result = KBTS__FEATURE_ID_hngl; break;+ case KBTS_FEATURE_TAG_hojo: Result = KBTS__FEATURE_ID_hojo; break;+ case KBTS_FEATURE_TAG_hwid: Result = KBTS__FEATURE_ID_hwid; break;+ case KBTS_FEATURE_TAG_ital: Result = KBTS__FEATURE_ID_ital; break;+ case KBTS_FEATURE_TAG_jalt: Result = KBTS__FEATURE_ID_jalt; break;+ case KBTS_FEATURE_TAG_jp78: Result = KBTS__FEATURE_ID_jp78; break;+ case KBTS_FEATURE_TAG_jp83: Result = KBTS__FEATURE_ID_jp83; break;+ case KBTS_FEATURE_TAG_jp90: Result = KBTS__FEATURE_ID_jp90; break;+ case KBTS_FEATURE_TAG_jp04: Result = KBTS__FEATURE_ID_jp04; break;+ case KBTS_FEATURE_TAG_kern: Result = KBTS__FEATURE_ID_kern; break;+ case KBTS_FEATURE_TAG_lfbd: Result = KBTS__FEATURE_ID_lfbd; break;+ case KBTS_FEATURE_TAG_liga: Result = KBTS__FEATURE_ID_liga; break;+ case KBTS_FEATURE_TAG_lnum: Result = KBTS__FEATURE_ID_lnum; break;+ case KBTS_FEATURE_TAG_locl: Result = KBTS__FEATURE_ID_locl; break;+ case KBTS_FEATURE_TAG_ltra: Result = KBTS__FEATURE_ID_ltra; break;+ case KBTS_FEATURE_TAG_ltrm: Result = KBTS__FEATURE_ID_ltrm; break;+ case KBTS_FEATURE_TAG_mark: Result = KBTS__FEATURE_ID_mark; break;+ case KBTS_FEATURE_TAG_mgrk: Result = KBTS__FEATURE_ID_mgrk; break;+ case KBTS_FEATURE_TAG_mkmk: Result = KBTS__FEATURE_ID_mkmk; break;+ case KBTS_FEATURE_TAG_mset: Result = KBTS__FEATURE_ID_mset; break;+ case KBTS_FEATURE_TAG_nalt: Result = KBTS__FEATURE_ID_nalt; break;+ case KBTS_FEATURE_TAG_nlck: Result = KBTS__FEATURE_ID_nlck; break;+ case KBTS_FEATURE_TAG_nukt: Result = KBTS__FEATURE_ID_nukt; break;+ case KBTS_FEATURE_TAG_onum: Result = KBTS__FEATURE_ID_onum; break;+ case KBTS_FEATURE_TAG_opbd: Result = KBTS__FEATURE_ID_opbd; break;+ case KBTS_FEATURE_TAG_ordn: Result = KBTS__FEATURE_ID_ordn; break;+ case KBTS_FEATURE_TAG_ornm: Result = KBTS__FEATURE_ID_ornm; break;+ case KBTS_FEATURE_TAG_palt: Result = KBTS__FEATURE_ID_palt; break;+ case KBTS_FEATURE_TAG_pcap: Result = KBTS__FEATURE_ID_pcap; break;+ case KBTS_FEATURE_TAG_pkna: Result = KBTS__FEATURE_ID_pkna; break;+ case KBTS_FEATURE_TAG_pnum: Result = KBTS__FEATURE_ID_pnum; break;+ case KBTS_FEATURE_TAG_pres: Result = KBTS__FEATURE_ID_pres; break;+ case KBTS_FEATURE_TAG_psts: Result = KBTS__FEATURE_ID_psts; break;+ case KBTS_FEATURE_TAG_pwid: Result = KBTS__FEATURE_ID_pwid; break;+ case KBTS_FEATURE_TAG_qwid: Result = KBTS__FEATURE_ID_qwid; break;+ case KBTS_FEATURE_TAG_rand: Result = KBTS__FEATURE_ID_rand; break;+ case KBTS_FEATURE_TAG_rclt: Result = KBTS__FEATURE_ID_rclt; break;+ case KBTS_FEATURE_TAG_rkrf: Result = KBTS__FEATURE_ID_rkrf; break;+ case KBTS_FEATURE_TAG_rlig: Result = KBTS__FEATURE_ID_rlig; break;+ case KBTS_FEATURE_TAG_rtbd: Result = KBTS__FEATURE_ID_rtbd; break;+ case KBTS_FEATURE_TAG_rtla: Result = KBTS__FEATURE_ID_rtla; break;+ case KBTS_FEATURE_TAG_rtlm: Result = KBTS__FEATURE_ID_rtlm; break;+ case KBTS_FEATURE_TAG_ruby: Result = KBTS__FEATURE_ID_ruby; break;+ case KBTS_FEATURE_TAG_rvrn: Result = KBTS__FEATURE_ID_rvrn; break;+ case KBTS_FEATURE_TAG_salt: Result = KBTS__FEATURE_ID_salt; break;+ case KBTS_FEATURE_TAG_sinf: Result = KBTS__FEATURE_ID_sinf; break;+ case KBTS_FEATURE_TAG_size: Result = KBTS__FEATURE_ID_size; break;+ case KBTS_FEATURE_TAG_smcp: Result = KBTS__FEATURE_ID_smcp; break;+ case KBTS_FEATURE_TAG_smpl: Result = KBTS__FEATURE_ID_smpl; break;+ case KBTS_FEATURE_TAG_ss01: Result = KBTS__FEATURE_ID_ss01; break;+ case KBTS_FEATURE_TAG_ss02: Result = KBTS__FEATURE_ID_ss02; break;+ case KBTS_FEATURE_TAG_ss03: Result = KBTS__FEATURE_ID_ss03; break;+ case KBTS_FEATURE_TAG_ss04: Result = KBTS__FEATURE_ID_ss04; break;+ case KBTS_FEATURE_TAG_ss05: Result = KBTS__FEATURE_ID_ss05; break;+ case KBTS_FEATURE_TAG_ss06: Result = KBTS__FEATURE_ID_ss06; break;+ case KBTS_FEATURE_TAG_ss07: Result = KBTS__FEATURE_ID_ss07; break;+ case KBTS_FEATURE_TAG_ss08: Result = KBTS__FEATURE_ID_ss08; break;+ case KBTS_FEATURE_TAG_ss09: Result = KBTS__FEATURE_ID_ss09; break;+ case KBTS_FEATURE_TAG_ss10: Result = KBTS__FEATURE_ID_ss10; break;+ case KBTS_FEATURE_TAG_ss11: Result = KBTS__FEATURE_ID_ss11; break;+ case KBTS_FEATURE_TAG_ss12: Result = KBTS__FEATURE_ID_ss12; break;+ case KBTS_FEATURE_TAG_ss13: Result = KBTS__FEATURE_ID_ss13; break;+ case KBTS_FEATURE_TAG_ss14: Result = KBTS__FEATURE_ID_ss14; break;+ case KBTS_FEATURE_TAG_ss15: Result = KBTS__FEATURE_ID_ss15; break;+ case KBTS_FEATURE_TAG_ss16: Result = KBTS__FEATURE_ID_ss16; break;+ case KBTS_FEATURE_TAG_ss17: Result = KBTS__FEATURE_ID_ss17; break;+ case KBTS_FEATURE_TAG_ss18: Result = KBTS__FEATURE_ID_ss18; break;+ case KBTS_FEATURE_TAG_ss19: Result = KBTS__FEATURE_ID_ss19; break;+ case KBTS_FEATURE_TAG_ss20: Result = KBTS__FEATURE_ID_ss20; break;+ case KBTS_FEATURE_TAG_ssty: Result = KBTS__FEATURE_ID_ssty; break;+ case KBTS_FEATURE_TAG_stch: Result = KBTS__FEATURE_ID_stch; break;+ case KBTS_FEATURE_TAG_subs: Result = KBTS__FEATURE_ID_subs; break;+ case KBTS_FEATURE_TAG_sups: Result = KBTS__FEATURE_ID_sups; break;+ case KBTS_FEATURE_TAG_swsh: Result = KBTS__FEATURE_ID_swsh; break;+ case KBTS_FEATURE_TAG_test: Result = KBTS__FEATURE_ID_test; break;+ case KBTS_FEATURE_TAG_titl: Result = KBTS__FEATURE_ID_titl; break;+ case KBTS_FEATURE_TAG_tnam: Result = KBTS__FEATURE_ID_tnam; break;+ case KBTS_FEATURE_TAG_tnum: Result = KBTS__FEATURE_ID_tnum; break;+ case KBTS_FEATURE_TAG_trad: Result = KBTS__FEATURE_ID_trad; break;+ case KBTS_FEATURE_TAG_twid: Result = KBTS__FEATURE_ID_twid; break;+ case KBTS_FEATURE_TAG_unic: Result = KBTS__FEATURE_ID_unic; break;+ case KBTS_FEATURE_TAG_valt: Result = KBTS__FEATURE_ID_valt; break;+ case KBTS_FEATURE_TAG_vapk: Result = KBTS__FEATURE_ID_vapk; break;+ case KBTS_FEATURE_TAG_vatu: Result = KBTS__FEATURE_ID_vatu; break;+ case KBTS_FEATURE_TAG_vchw: Result = KBTS__FEATURE_ID_vchw; break;+ case KBTS_FEATURE_TAG_vert: Result = KBTS__FEATURE_ID_vert; break;+ case KBTS_FEATURE_TAG_vhal: Result = KBTS__FEATURE_ID_vhal; break;+ case KBTS_FEATURE_TAG_vkna: Result = KBTS__FEATURE_ID_vkna; break;+ case KBTS_FEATURE_TAG_vkrn: Result = KBTS__FEATURE_ID_vkrn; break;+ case KBTS_FEATURE_TAG_vpal: Result = KBTS__FEATURE_ID_vpal; break;+ case KBTS_FEATURE_TAG_vrt2: Result = KBTS__FEATURE_ID_vrt2; break;+ case KBTS_FEATURE_TAG_vrtr: Result = KBTS__FEATURE_ID_vrtr; break;+ case KBTS_FEATURE_TAG_zero: Result = KBTS__FEATURE_ID_zero; break;+ default: break;+ }+ return Result;+}++static kbts_s32 kbts__UnicodeParentDeltas[1679] = {+ 132,133,134,135,244,246,248,250,252,254,315,351,416,418,7678,7680,7682,7792,7794,132,133,134,135,275,277,279,281,283,285,346,382,447,+ 449,7709,7711,7713,7823,7825,131,132,133,134,174,176,178,180,182,416,418,452,7604,7606,7764,7766,7768,131,132,133,134,205,207,209,211,213,+ 447,449,483,7635,7637,7795,7797,7799,127,128,129,130,131,132,160,162,164,365,416,418,454,7584,7744,7746,127,128,129,130,131,132,191,193,+ 195,396,447,449,485,7615,7775,7777,131,132,133,134,135,222,224,226,306,355,380,414,416,448,7774,7776,131,132,133,134,135,253,255,257,+ 337,386,411,445,447,479,7805,7807,131,132,133,134,223,225,227,229,231,390,447,449,7651,7807,7809,131,132,133,134,192,194,196,198,359,+ 416,418,7620,7776,7778,132,134,254,442,7702,7712,7802,7804,7806,7808,-10,17,7031,7032,7101,7173,7191,7192,7197,131,214,216,218,395,7639,7641,7643,+ 7645,131,245,247,249,426,7670,7672,7674,7676,132,285,287,473,7733,7833,7835,7837,7839,227,229,231,415,417,7655,7657,7661,6,8,7051,7052,7093,+ 7195,7196,7201,189,439,7611,7613,7615,7617,7619,7726,239,241,423,7671,7673,7675,7677,7715,-5,6991,6992,7103,7167,7168,7170,7173,258,260,262,446,448,+ 7686,7688,7692,182,184,186,188,384,398,7610,213,215,217,219,415,429,7641,232,234,236,238,422,7662,7664,263,265,267,269,453,7693,7695,-15,+ 17,7071,7072,7231,7232,7233,220,470,7642,7644,7646,7648,7650,-11,7031,7032,7207,7208,7209,7211,254,7690,7692,7694,7696,7698,7713,270,272,454,7702,7704,+ 7706,7708,206,208,210,7627,7631,7633,-23,6,7092,7235,7236,7237,-26,7103,7104,7249,7251,7549,235,413,7653,7655,7657,8415,237,239,241,7658,7662,7664,+ -9,7017,7018,7101,7180,7183,5,7063,7064,7091,7210,7213,256,258,260,7703,7705,7707,171,7591,7593,7595,7597,7599,287,289,291,7734,7736,7738,202,7622,+ 7624,7626,7628,7630,285,7721,7723,7725,7727,7729,-3,-2,-1,3,4,1,2,3,4,5,132,164,166,168,170,-14,7057,7058,7219,7221,132,195,+ 197,199,201,7481,7483,7485,7487,7489,7482,7484,7486,7488,7490,204,382,7622,7624,7626,2,4,6,64,3,4,5,7,-21,203,205,207,2,4,+ 6,112,-11,1,202,204,2,4,6,128,1,37,171,173,-8,7003,7004,7101,-19,7081,7082,7257,27,172,174,176,-13,7043,7044,7219,218,220,+ 222,224,249,251,253,255,13,7041,7042,7097,7596,7598,7600,7602,7619,7621,7623,7625,7637,7639,7641,7643,7645,7647,7649,7651,7650,7652,7654,7656,7668,7670,+ 7672,7674,7676,7678,7680,7682,-33,-32,-31,-58,7176,7181,-27,7191,7196,-5,-4,-2,1,2,4,1,3,5,2,3,5,1,4,5,-21,-20,+ 193,2,4,16,3,5,6,14,15,16,27,28,162,312,7512,7514,343,7543,7545,7585,7587,7589,733,7961,8005,7616,7618,7620,7634,7636,7638,7665,+ 7667,7669,22891,22892,23346,31318,31405,162165,31650,31843,31932,35977,36182,166849,36278,36572,167227,36626,36698,36797,62785,62786,62816,25280,156147,156148,37394,37755,168385,38990,39065,169662,+ 62814,62815,62816,39089,39163,169757,40312,40387,171144,173234,173235,173236,-29,-28,12,22,161,163,140,167,171,198,253,279,203,390,284,310,7109,7176,7111,7190,+ 7087,7206,7203,7204,7426,7428,7428,7430,7684,7686,309,8294,7687,7689,7699,7701,7718,7720,7730,7732,25135,25233,25194,25291,25286,25458,25477,25572,27117,27183,27997,28089,+ 28255,28607,28357,28407,28458,28550,28458,28610,28513,28603,28875,28962,30692,30693,24507,155384,32406,32493,27530,158375,28470,159303,33613,33756,28625,159459,29500,160322,34266,34388,34540,34678,+ 29402,160600,30216,161096,35034,35118,30351,161459,32788,163609,32908,163783,35621,35704,37790,37917,32943,164035,33018,163837,40630,40631,41398,41506,42137,42203,33247,163972,54624,54625,33631,164350,+ 33716,164428,33778,164808,34352,165055,34921,165612,35453,166134,35790,166464,62788,62816,62816,62826,36046,166794,62816,62834,62816,62838,37311,168029,37752,168382,37810,168510,62816,62843,161426,161674,+ 38130,168825,38679,169659,39225,169818,39337,169999,39518,170436,40398,171018,42033,172614,42209,172718,164391,164392,169819,169821,42724,173276,42572,173332,42877,173358,42832,173379,170354,170355,42858,173405,+ 42927,173406,43001,173641,43196,173670,43237,173761,171308,171309,43338,173859,172737,172738,43650,174167,47771,178448,178804,178805,48949,179530,-99324,-90618,-87924,-84098,-80132,-77179,-77172,-3295,-163,-70,+ -60,-59,-36,-16,-6,9,10,26,32,34,41,48,51,55,56,59,60,63,66,67,78,81,100,118,169,187,200,278,282,294,340,720,+ 835,7085,7086,7110,7112,7156,7234,7243,7261,7273,7276,7277,7434,7440,7452,7458,7519,7609,7640,8009,8079,8739,8753,8754,21533,21757,22403,22533,22797,22850,23095,23227,+ 23233,23281,23298,23360,23371,23380,23445,23673,23963,24010,24281,24349,24361,24836,24879,24891,24946,24988,25094,25170,25195,25276,25316,25326,25344,25350,25352,25422,25430,25435,25464,25496,+ 25532,25561,25674,25675,25959,26097,26171,26173,26193,26425,26493,26543,26589,26627,26653,26703,26718,26756,26801,26921,26923,26951,26960,26999,27073,27179,27192,27217,27250,27309,27312,27340,+ 27464,27707,27770,27782,27832,28049,28122,28147,28267,28324,28331,28608,28656,28666,28698,28799,28894,28935,28936,28952,28977,29008,29015,29045,29116,29367,29393,29426,29487,29526,29684,29686,+ 29710,29867,29894,29915,29989,30055,30069,30405,30408,30477,30542,30561,30734,30805,30831,30919,30920,31016,31027,31082,31114,31253,31329,31341,31401,31464,31513,31603,31641,31645,31768,31776,+ 31816,31823,31892,31935,31972,32043,32045,32084,32095,32103,32104,32307,32472,32556,32570,32701,32715,32724,32763,32776,32859,32870,32873,32893,32949,32955,32965,32988,33012,33023,33028,33030,+ 33038,33053,33123,33210,33356,33388,33445,33526,33630,33642,33663,33740,33795,33809,33908,33926,33927,34059,34105,34117,34135,34152,34204,34243,34270,34273,34299,34344,34351,34354,34532,34563,+ 34594,34618,34800,34802,34846,34877,34890,35031,35039,35127,35170,35206,35327,35379,35391,35439,35457,35631,35634,35699,35773,35776,35820,35834,35882,35884,35898,35996,36049,36071,36074,36094,+ 36206,36343,36373,36377,36443,36446,36636,36665,37113,37178,37315,37331,37334,37344,37389,37453,37469,37523,37573,37693,37694,37714,37822,37837,37846,37873,37925,37977,37984,37996,38049,38135,+ 38202,38357,38441,38457,38461,38492,38514,38517,38540,38556,38590,38601,38700,38703,38730,38800,38820,38911,39000,39061,39126,39128,39210,39246,39296,39312,39342,39357,39397,39414,39487,39501,+ 39574,39640,39641,39706,39707,39736,39771,39850,39856,39889,39921,40124,40165,40169,40314,40318,40374,40407,40575,40793,40888,40900,40928,40974,40990,41059,41074,41230,41259,41274,41362,41418,+ 41465,41616,41648,41658,41772,41860,41936,42061,42273,42276,42288,42302,42407,42408,42447,42448,42577,42624,42634,42668,42735,42746,42814,42871,42872,42885,42889,42928,42932,42949,43023,43025,+ 43050,43063,43086,43088,43108,43212,43233,43253,43257,43274,43311,43396,43418,43430,43431,43433,43562,43673,43716,43721,43731,43763,43813,43828,43837,43866,44106,44197,44287,45331,45553,45851,+ 46452,46778,47491,47538,47676,47803,48104,48191,48639,48746,49225,49737,50294,50458,50655,50670,50678,50721,51392,52429,52652,53712,55046,55194,55959,56301,56665,56996,57719,57784,58229,60629,+ 60936,61695,61907,61909,62155,62198,62454,62765,63201,154337,154373,154379,154388,154394,154398,154458,154792,154895,155083,155657,155716,155742,155867,155936,156119,156186,156370,156464,156729,156771,157143,157170,+ 157457,157550,157615,157899,157907,157938,158030,158191,158474,158700,158735,158751,158816,158907,158996,159017,159101,159535,159951,159977,159983,160097,160099,160192,160223,160312,160338,160404,160427,160472,160526,160560,+ 160589,160590,160611,160840,160916,160950,160951,161207,161223,161238,161239,161248,161262,161335,161357,161401,161404,161456,161496,161505,161506,161524,161534,161541,161672,161833,161863,161920,162000,162063,162077,162175,+ 162275,162300,162603,162669,162727,162825,162922,162944,162950,162964,163226,163228,163441,163596,163600,163692,164096,164287,164650,164856,164880,164968,165036,165075,165095,165254,165278,165294,165520,165540,165586,165624,+ 165762,165829,165847,165997,166043,166050,166093,166106,166138,166220,166305,166469,166555,166617,166677,166784,166796,166810,166850,166867,166889,166960,166973,167063,167084,167253,167297,167325,167374,167442,167491,167680,+ 167750,167846,167890,168022,168079,168134,168165,168283,168317,168329,168377,168404,168505,168580,168680,168797,169000,169030,169039,169050,169117,169177,169211,169240,169273,169299,169319,169340,169406,169442,169476,169559,+ 169624,169634,169681,169722,169727,169737,169776,169822,169950,170015,170150,170183,170192,170242,170273,170287,170295,170386,170455,170457,170459,170526,170569,170589,170631,170656,170756,170768,170772,170809,170937,170989,+ 171031,171074,171091,171117,171123,171133,171158,171178,171361,171520,171581,171592,171638,171661,171729,171773,171836,171843,171862,171875,171876,171880,171948,172068,172070,172103,172127,172164,172234,172341,172342,172507,+ 172541,172680,172694,172701,172769,172784,172850,172875,172958,173015,173046,173061,173109,173129,173134,173144,173164,173244,173268,173283,173348,173484,173488,173531,173541,173595,173608,173678,173684,173696,173704,173722,+ 173740,173741,173755,173791,173884,173886,173888,173936,173966,174085,174155,174244,174413,174529,174531,174537,175296,175385,175393,175423,175674,175824,175946,176003,176010,176140,176218,176903,176911,177043,177097,177128,+ 177223,177230,177233,177276,177406,177443,177529,177580,177691,177725,177772,177863,177981,178014,178217,178286,178358,178437,178487,178498,178712,178814,179072,179159,179364,179414,179605,179637,179656,179693,179803,179860,+ 180071,180102,180152,180175,180238,180262,180308,180469,180588,180601,181007,181056,181082,181102,181519,+};++static kbts_u8 kbts__ScriptExtensions[447] = {+ 6,18,24,25,35,37,41,42,43,45,47,72,79,80,112,132,11,28,32,72,77,155,160,13,72,72,155,22,25,28,45,72,+ 112,141,146,22,28,45,72,119,141,146,159,22,28,72,157,42,72,141,143,155,19,22,25,28,43,45,72,119,143,157,159,25,+ 37,42,43,62,72,25,35,54,72,112,143,146,157,159,5,28,35,43,45,54,72,112,143,146,35,72,143,22,28,72,119,22,+ 72,146,39,72,28,72,159,45,72,112,159,22,35,62,72,143,22,35,72,143,22,72,143,19,22,43,72,141,155,19,72,159,+ 25,45,28,112,28,42,5,41,42,4,40,51,103,143,154,167,4,143,154,1,4,40,51,103,143,154,167,1,4,51,83,84,+ 117,126,135,143,4,154,167,11,32,44,46,48,61,72,82,118,131,150,153,158,11,32,44,46,48,61,72,82,118,150,153,158,+ 11,32,34,44,46,47,48,61,69,80,82,86,100,108,118,136,142,149,150,153,158,11,32,34,44,46,47,48,49,61,69,74,+ 80,82,86,100,108,118,136,142,149,150,153,158,32,34,60,80,11,20,142,48,96,46,68,44,150,61,100,161,20,97,146,41,+ 42,72,16,52,144,145,94,124,11,32,44,61,32,131,32,61,82,118,150,153,32,100,11,32,44,61,82,100,118,136,153,158,+ 161,32,44,61,161,28,72,143,72,94,124,18,41,42,78,110,116,18,45,91,110,32,44,72,25,72,6,116,6,18,41,60,+ 79,110,129,1,4,110,24,152,13,24,50,55,62,94,168,13,24,50,55,62,94,124,168,13,24,50,55,62,94,156,168,13,+ 24,50,55,62,77,94,156,168,13,24,50,55,62,168,24,55,62,24,72,32,34,46,48,60,61,68,69,80,82,93,100,131,+ 149,158,161,32,34,46,48,60,61,68,69,80,93,100,131,149,158,161,32,34,46,48,60,68,69,80,93,149,158,32,34,46,+ 48,60,68,69,80,93,131,149,158,11,32,161,32,150,64,72,97,15,59,4,103,26,27,76,26,76,26,75,76,4,25,+};++static kbts_u8 kbts__UnicodeDecomposition_PageIndices[17407] = {+ 0,1,1,2,3,4,5,6,7,1,1,1,1,8,9,10,11,12,1,13,1,1,1,1,14,1,1,15,1,1,1,1,+ 1,1,1,1,16,17,1,18,19,20,1,1,1,21,1,22,1,23,1,24,1,25,1,26,1,1,1,1,1,27,28,1,+ 29,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,30,31,+ 1,1,1,1,1,1,1,1,1,1,1,1,32,33,1,1,1,1,1,1,1,1,1,1,34,35,36,37,38,39,40,41,+ 42,1,1,1,43,1,44,45,46,47,48,49,50,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,51,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,52,53,54,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,55,56,57,58,59,60,61,62,63,64,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,65,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,66,1,67,1,1,1,1,1,1,1,1,68,69,70,1,1,71,1,1,1,72,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,73,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,74,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,75,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,76,77,78,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 79,80,81,82,83,84,85,86,87,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+};++static kbts_u64 kbts__UnicodeDecomposition_Data[5632] = {+ 52776558133248ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 6442451206ull,6450839814ull,6459228422ull,6467617030ull,6509560070ull,6526337286ull,0ull,6769606926ull,6442451222ull,6450839830ull,6459228438ull,6509560086ull,6442451238ull,6450839846ull,6459228454ull,6509560102ull,0ull,6467617082ull,6442451262ull,6450839870ull,6459228478ull,6467617086ull,6509560126ull,0ull,0ull,6442451286ull,6450839894ull,6459228502ull,6509560150ull,6450839910ull,0ull,0ull,+ 6442451334ull,6450839942ull,6459228550ull,6467617158ull,6509560198ull,6526337414ull,0ull,6769607054ull,6442451350ull,6450839958ull,6459228566ull,6509560214ull,6442451366ull,6450839974ull,6459228582ull,6509560230ull,0ull,6467617210ull,6442451390ull,6450839998ull,6459228606ull,6467617214ull,6509560254ull,0ull,0ull,6442451414ull,6450840022ull,6459228630ull,6509560278ull,6450840038ull,0ull,6509560294ull,+ 6476005638ull,6476005766ull,6492782854ull,6492782982ull,6777995526ull,6777995654ull,6450839822ull,6450839950ull,6459228430ull,6459228558ull,6501171470ull,6501171598ull,6543114510ull,6543114638ull,6543114514ull,6543114642ull,0ull,0ull,6476005654ull,6476005782ull,6492782870ull,6492782998ull,6501171478ull,6501171606ull,6777995542ull,6777995670ull,6543114518ull,6543114646ull,6459228446ull,6459228574ull,6492782878ull,6492783006ull,+ 6501171486ull,6501171614ull,6769606942ull,6769607070ull,6459228450ull,6459228578ull,0ull,0ull,6467617062ull,6467617190ull,6476005670ull,6476005798ull,6492782886ull,6492783014ull,6777995558ull,6777995686ull,6501171494ull,0ull,0ull,0ull,6459228458ull,6459228586ull,6769606958ull,6769607086ull,0ull,6450839858ull,6450839986ull,6769606962ull,6769607090ull,6543114546ull,6543114674ull,0ull,+ 0ull,0ull,0ull,6450839866ull,6450839994ull,6769606970ull,6769607098ull,6543114554ull,6543114682ull,0ull,0ull,0ull,6476005694ull,6476005822ull,6492782910ull,6492783038ull,6534725950ull,6534726078ull,0ull,0ull,6450839882ull,6450840010ull,6769606986ull,6769607114ull,6543114570ull,6543114698ull,6450839886ull,6450840014ull,6459228494ull,6459228622ull,6769606990ull,6769607118ull,+ 6543114574ull,6543114702ull,6769606994ull,6769607122ull,6543114578ull,6543114706ull,0ull,0ull,6467617110ull,6467617238ull,6476005718ull,6476005846ull,6492782934ull,6492783062ull,6526337366ull,6526337494ull,6534725974ull,6534726102ull,6777995606ull,6777995734ull,6459228510ull,6459228638ull,6459228518ull,6459228646ull,6509560166ull,6450839914ull,6450840042ull,6501171562ull,6501171690ull,6543114602ull,6543114730ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 6668943678ull,6668943806ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,6668943702ull,6668943830ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,6543114502ull,6543114630ull,6543114534ull,6543114662ull,6543114558ull,6543114686ull,6543114582ull,6543114710ull,6476006258ull,6476006386ull,6450840434ull,6450840562ull,6543115122ull,6543115250ull,6442451826ull,6442451954ull,0ull,6476006162ull,6476006290ull,+ 6476007578ull,6476007582ull,6476006170ull,6476006298ull,0ull,0ull,6543114526ull,6543114654ull,6543114542ull,6543114670ull,6777995582ull,6777995710ull,6476007338ull,6476007342ull,6543115998ull,6543116874ull,6543114666ull,0ull,0ull,0ull,6450839838ull,6450839966ull,0ull,0ull,6442451258ull,6442451386ull,6450840342ull,6450840470ull,6450840346ull,6450840474ull,6450840418ull,6450840546ull,+ 6568280326ull,6568280454ull,6585057542ull,6585057670ull,6568280342ull,6568280470ull,6585057558ull,6585057686ull,6568280358ull,6568280486ull,6585057574ull,6585057702ull,6568280382ull,6568280510ull,6585057598ull,6585057726ull,6568280394ull,6568280522ull,6585057610ull,6585057738ull,6568280406ull,6568280534ull,6585057622ull,6585057750ull,6761218382ull,6761218510ull,6761218386ull,6761218514ull,0ull,0ull,6543114530ull,6543114658ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,6501171462ull,6501171590ull,6769606934ull,6769607062ull,6476006234ull,6476006362ull,6476006230ull,6476006358ull,6501171518ull,6501171646ull,6476007610ull,6476007614ull,6476005734ull,6476005862ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 3073ull,3077ull,0ull,3149ull,6450842658ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,2789ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,237ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,6450840226ull,6450843206ull,733ull,6450843222ull,6450843230ull,6450843238ull,0ull,6450843262ull,0ull,6450843286ull,6450843302ull,6450843434ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,6509563494ull,6509563542ull,6450843334ull,6450843350ull,6450843358ull,6450843366ull,6450843438ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,6509563622ull,6509563670ull,6450843390ull,6450843414ull,6450843430ull,0ull,0ull,0ull,0ull,6450843466ull,6509563722ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 6442455126ull,6509563990ull,0ull,6450843726ull,0ull,0ull,0ull,6509563930ull,0ull,0ull,0ull,0ull,6450843754ull,6442455138ull,6492786830ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,6492786786ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,6492786914ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,6442455254ull,6509564118ull,0ull,6450843854ull,0ull,0ull,0ull,6509564250ull,0ull,0ull,0ull,0ull,6450843882ull,6442455266ull,6492786958ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,6568284626ull,6568284630ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,6492786778ull,6492786906ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,6492786754ull,6492786882ull,6509563970ull,6509564098ull,0ull,0ull,6492786774ull,6492786902ull,0ull,0ull,6509564770ull,6509564774ull,6509563994ull,6509564122ull,6509563998ull,6509564126ull,+ 0ull,0ull,6476009570ull,6476009698ull,6509564002ull,6509564130ull,6509564026ull,6509564154ull,0ull,0ull,6509564834ull,6509564838ull,6509564086ull,6509564214ull,6476009614ull,6476009742ull,6509564046ull,6509564174ull,6534729870ull,6534729998ull,6509564062ull,6509564190ull,0ull,0ull,6509564078ull,6509564206ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,13581162654ull,13589551262ull,13589551394ull,13597939870ull,13589551402ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 13589551958ull,0ull,13589551878ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,13589551946ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,19830678690ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,19830678734ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,19830678614ull,19830678618ull,19830678622ull,19830678642ull,19830678662ull,19830678666ull,19830678702ull,19830678718ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,20921198366ull,21130913566ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,20904421054ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,21978163402ull,0ull,0ull,21978163426ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,21978163290ull,21978163294ull,21978163314ull,0ull,0ull,21978163374ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,24343751966ull,0ull,0ull,24142425374ull,24352140574ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,24125648006ull,24125648010ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,25216167706ull,25216167710ull,25425882906ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,26491236634ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 27556590334ull,0ull,0ull,0ull,0ull,0ull,0ull,27556590362ull,27564978970ull,0ull,27397206810ull,27556590378ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,28437394714ull,28437394718ull,28647109914ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,29611800422ull,0ull,29653743462ull,29611800434ull,29787961190ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,33747385610ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,33747385650ull,0ull,0ull,0ull,0ull,33747385670ull,0ull,0ull,0ull,0ull,33747385690ull,0ull,0ull,0ull,0ull,33747385710ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,33730608386ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,33168571846ull,0ull,33185349062ull,33286012618ull,0ull,33286012622ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,33286012358ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,33747385930ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,33747385970ull,0ull,0ull,+ 0ull,0ull,33747385990ull,0ull,0ull,0ull,0ull,33747386010ull,0ull,0ull,0ull,0ull,33747386030ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,33730608706ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,34745630870ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,35235358072582ull,35235366461190ull,+ 35235374849798ull,0ull,0ull,0ull,35235408404230ull,35235416792838ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,58426682390ull,0ull,58426682398ull,0ull,58426682406ull,0ull,58426682414ull,0ull,58426682422ull,0ull,0ull,0ull,58426682438ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,58426682602ull,0ull,58426682610ull,0ull,0ull,+ 58426682618ull,58426682622ull,0ull,58426682634ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 6752829702ull,6752829830ull,6501171466ull,6501171594ull,6736052490ull,6736052618ull,6853493002ull,6853493130ull,6450840350ull,6450840478ull,6501171474ull,6501171602ull,6736052498ull,6736052626ull,6853493010ull,6853493138ull,6769606930ull,6769607058ull,6819938578ull,6819938706ull,6442452042ull,6442452046ull,6450840650ull,6450840654ull,6819938582ull,6819938710ull,6845104406ull,6845104534ull,6492784802ull,6492784806ull,6501171482ull,6501171610ull,+ 6476005662ull,6476005790ull,6501171490ull,6501171618ull,6736052514ull,6736052642ull,6509560098ull,6509560226ull,6769606946ull,6769607074ull,6828327202ull,6828327330ull,6845104422ull,6845104550ull,6450840382ull,6450840510ull,6450839854ull,6450839982ull,6736052526ull,6736052654ull,6853493038ull,6853493166ull,6736052530ull,6736052658ull,6476036314ull,6476036318ull,6853493042ull,6853493170ull,6819938610ull,6819938738ull,6450839862ull,6450839990ull,+ 6501171510ull,6501171638ull,6736052534ull,6736052662ull,6501171514ull,6501171642ull,6736052538ull,6736052666ull,6853493050ull,6853493178ull,6819938618ull,6819938746ull,6450840406ull,6450840534ull,6509560662ull,6509560790ull,6442452274ull,6442452278ull,6450840882ull,6450840886ull,6450839874ull,6450840002ull,6501171522ull,6501171650ull,6501171530ull,6501171658ull,6736052554ull,6736052682ull,6476036458ull,6476036462ull,6853493066ull,6853493194ull,+ 6501171534ull,6501171662ull,6736052558ull,6736052686ull,6501172586ull,6501172590ull,6501172610ull,6501172614ull,6501202314ull,6501202318ull,6501171538ull,6501171666ull,6736052562ull,6736052690ull,6853493074ull,6853493202ull,6819938642ull,6819938770ull,6744441174ull,6744441302ull,6845104470ull,6845104598ull,6819938646ull,6819938774ull,6450840994ull,6450840998ull,6509561258ull,6509561262ull,6467617114ull,6467617242ull,6736052570ull,6736052698ull,+ 6442451294ull,6442451422ull,6450839902ull,6450840030ull,6509560158ull,6509560286ull,6501171550ull,6501171678ull,6736052574ull,6736052702ull,6501171554ull,6501171682ull,6509560162ull,6509560290ull,6501171558ull,6501171686ull,6459228522ull,6459228650ull,6736052586ull,6736052714ull,6853493098ull,6853493226ull,6853493154ull,6509560274ull,6526337502ull,6526337510ull,0ull,6501172734ull,0ull,0ull,0ull,0ull,+ 6736052486ull,6736052614ull,6517948678ull,6517948806ull,6450840330ull,6450840458ull,6442451722ull,6442451850ull,6517949194ull,6517949322ull,6467617546ull,6467617674ull,6459259522ull,6459259526ull,6450840586ull,6450840590ull,6442451978ull,6442451982ull,6517949450ull,6517949454ull,6467617802ull,6467617806ull,6492813954ull,6492813958ull,6736052502ull,6736052630ull,6517948694ull,6517948822ull,6467617046ull,6467617174ull,6450840362ull,6450840490ull,+ 6442451754ull,6442451882ull,6517949226ull,6517949354ull,6467617578ull,6467617706ull,6459259618ull,6459259622ull,6517948710ull,6517948838ull,6736052518ull,6736052646ull,6736052542ull,6736052670ull,6517948734ull,6517948862ull,6450840402ull,6450840530ull,6442451794ull,6442451922ull,6517949266ull,6517949394ull,6467617618ull,6467617746ull,6459259698ull,6459259702ull,6450841218ull,6450841222ull,6442452610ull,6442452614ull,6517950082ull,6517950086ull,+ 6467618434ull,6467618438ull,6736053890ull,6736053894ull,6736052566ull,6736052694ull,6517948758ull,6517948886ull,6450841278ull,6450841282ull,6442452670ull,6442452674ull,6517950142ull,6517950146ull,6467618494ull,6467618498ull,6736053950ull,6736053954ull,6442451302ull,6442451430ull,6736052582ull,6736052710ull,6517948774ull,6517948902ull,6467617126ull,6467617254ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 6601838278ull,6610226886ull,6442482690ull,6442482694ull,6450871298ull,6450871302ull,6996130818ull,6996130822ull,6601838150ull,6610226758ull,6442482722ull,6442482726ull,6450871330ull,6450871334ull,6996130850ull,6996130854ull,6601838294ull,6610226902ull,6442482754ull,6442482758ull,6450871362ull,6450871366ull,0ull,0ull,6601838166ull,6610226774ull,6442482786ull,6442482790ull,6450871394ull,6450871398ull,0ull,0ull,+ 6601838302ull,6610226910ull,6442482818ull,6442482822ull,6450871426ull,6450871430ull,6996130946ull,6996130950ull,6601838174ull,6610226782ull,6442482850ull,6442482854ull,6450871458ull,6450871462ull,6996130978ull,6996130982ull,6601838310ull,6610226918ull,6442482882ull,6442482886ull,6450871490ull,6450871494ull,6996131010ull,6996131014ull,6601838182ull,6610226790ull,6442482914ull,6442482918ull,6450871522ull,6450871526ull,6996131042ull,6996131046ull,+ 6601838334ull,6610226942ull,6442482946ull,6442482950ull,6450871554ull,6450871558ull,0ull,0ull,6601838206ull,6610226814ull,6442482978ull,6442482982ull,6450871586ull,6450871590ull,0ull,0ull,6601838358ull,6610226966ull,6442483010ull,6442483014ull,6450871618ull,6450871622ull,6996131138ull,6996131142ull,0ull,6610226838ull,0ull,6442483046ull,0ull,6450871654ull,0ull,6996131174ull,+ 6601838374ull,6610226982ull,6442483074ull,6442483078ull,6450871682ull,6450871686ull,6996131202ull,6996131206ull,6601838246ull,6610226854ull,6442483106ull,6442483110ull,6450871714ull,6450871718ull,6996131234ull,6996131238ull,6442454726ull,3761ull,6442454742ull,3765ull,6442454750ull,3769ull,6442454758ull,3773ull,6442454782ull,3889ull,6442454806ull,3893ull,6442454822ull,3897ull,0ull,0ull,+ 7021296642ull,7021296646ull,7021296650ull,7021296654ull,7021296658ull,7021296662ull,7021296666ull,7021296670ull,7021296674ull,7021296678ull,7021296682ull,7021296686ull,7021296690ull,7021296694ull,7021296698ull,7021296702ull,7021296770ull,7021296774ull,7021296778ull,7021296782ull,7021296786ull,7021296790ull,7021296794ull,7021296798ull,7021296802ull,7021296806ull,7021296810ull,7021296814ull,7021296818ull,7021296822ull,7021296826ull,7021296830ull,+ 7021297026ull,7021297030ull,7021297034ull,7021297038ull,7021297042ull,7021297046ull,7021297050ull,7021297054ull,7021297058ull,7021297062ull,7021297066ull,7021297070ull,7021297074ull,7021297078ull,7021297082ull,7021297086ull,6492786374ull,6476009158ull,7021297090ull,7021268678ull,7021268658ull,0ull,6996102854ull,7021297370ull,6492786246ull,6476009030ull,6442454598ull,3609ull,7021268550ull,0ull,3813ull,0ull,+ 0ull,6996099746ull,7021297106ull,7021268702ull,7021268666ull,0ull,6996102878ull,7021297434ull,6442454614ull,3617ull,6442454622ull,3621ull,7021268574ull,6442483454ull,6450872062ull,6996131582ull,6492786406ull,6476009190ull,6442454826ull,3649ull,0ull,0ull,6996102886ull,6996102954ull,6492786278ull,6476009062ull,6442454630ull,3625ull,0ull,6442483706ull,6450872314ull,6996131834ull,+ 6492786454ull,6476009238ull,6442454830ull,3777ull,6601838342ull,6610226950ull,6996102934ull,6996102958ull,6492786326ull,6476009110ull,6442454678ull,3641ull,6610226822ull,6442451618ull,3605ull,385ull,0ull,0ull,7021297138ull,7021268774ull,7021268794ull,0ull,6996102950ull,7021297626ull,6442454654ull,3633ull,6442454694ull,3645ull,7021268646ull,721ull,0ull,0ull,+ 32777ull,32781ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,32833ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,3749ull,0ull,0ull,0ull,301ull,789ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,6912247362ull,6912247370ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,6912247378ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,6912247618ull,6912247634ull,6912247626ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,6912247822ull,0ull,0ull,0ull,0ull,6912247842ull,0ull,0ull,6912247854ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,6912247950ull,0ull,6912247958ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,6912248050ull,0ull,0ull,6912248078ull,0ull,0ull,6912248086ull,0ull,6912248098ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 6912213238ull,0ull,6912248198ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,6912248118ull,6912213234ull,6912213242ull,6912248210ull,6912248214ull,0ull,0ull,6912248266ull,6912248270ull,0ull,0ull,6912248282ull,6912248286ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 6912248298ull,6912248302ull,0ull,0ull,6912248330ull,6912248334ull,0ull,0ull,6912248346ull,6912248350ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,6912248458ull,6912248482ull,6912248486ull,6912248494ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 6912248306ull,6912248310ull,6912248390ull,6912248394ull,0ull,0ull,0ull,0ull,0ull,0ull,6912248522ull,6912248526ull,6912248530ull,6912248534ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,49185ull,49189ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,6912256886ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,104362721582ull,0ull,104362721590ull,0ull,104362721598ull,0ull,104362721606ull,0ull,104362721614ull,0ull,104362721622ull,0ull,104362721630ull,0ull,104362721638ull,0ull,104362721646ull,0ull,104362721654ull,0ull,+ 104362721662ull,0ull,104362721670ull,0ull,0ull,104362721682ull,0ull,104362721690ull,0ull,104362721698ull,0ull,0ull,0ull,0ull,0ull,0ull,104362721726ull,104371110334ull,0ull,104362721738ull,104371110346ull,0ull,104362721750ull,104371110358ull,0ull,104362721762ull,104371110370ull,0ull,104362721774ull,104371110382ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,104362721562ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,104362721910ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,104362721966ull,0ull,104362721974ull,0ull,104362721982ull,0ull,104362721990ull,0ull,104362721998ull,0ull,104362722006ull,0ull,104362722014ull,0ull,104362722022ull,0ull,104362722030ull,0ull,104362722038ull,0ull,+ 104362722046ull,0ull,104362722054ull,0ull,0ull,104362722066ull,0ull,104362722074ull,0ull,104362722082ull,0ull,0ull,0ull,0ull,0ull,0ull,104362722110ull,104371110718ull,0ull,104362722122ull,104371110730ull,0ull,104362722134ull,104371110742ull,0ull,104362722146ull,104371110754ull,0ull,104362722158ull,104371110766ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,104362721946ull,0ull,0ull,104362722238ull,104362722242ull,104362722246ull,104362722250ull,0ull,0ull,0ull,104362722294ull,0ull,+ 143649ull,105425ull,146217ull,144161ull,113477ull,80073ull,85909ull,163441ull,163441ull,91461ull,149317ull,87581ull,91425ull,100313ull,121253ull,130581ull,137469ull,138985ull,140257ull,148029ull,108553ull,111725ull,115557ull,118649ull,135413ull,148905ull,157637ull,80393ull,85461ull,109585ull,116845ull,137397ull,+ 161913ull,95553ull,114605ull,137013ull,140689ull,101157ull,132961ull,139389ull,97065ull,105565ull,112041ull,117745ull,148281ull,81433ull,83677ull,84857ull,103185ull,109389ull,116801ull,121757ull,131077ull,137241ull,137585ull,145341ull,154825ull,159165ull,161769ull,123441ull,124413ull,128641ull,134949ull,150545ull,+ 162301ull,142169ull,91005ull,97297ull,127361ull,131577ull,117129ull,123689ull,144137ull,154589ull,90977ull,94601ull,108621ull,112489ull,113725ull,128189ull,129245ull,153901ull,84809ull,131629ull,83825ull,83761ull,125041ull,128761ull,135109ull,154069ull,142849ull,101181ull,108553ull,142329ull,80101ull,94109ull,+ 98377ull,118301ull,120257ull,85085ull,123885ull,81661ull,97957ull,79925ull,111409ull,103905ull,128137ull,85773ull,90489ull,121861ull,135461ull,141993ull,110313ull,147137ull,111137ull,101369ull,134037ull,102017ull,120213ull,80569ull,83365ull,83749ull,107013ull,127901ull,133565ull,142153ull,149309ull,84949ull,+ 86281ull,91597ull,97201ull,104213ull,114681ull,124073ull,153269ull,158121ull,162397ull,162617ull,84589ull,105241ull,110045ull,146825ull,96721ull,99905ull,100353ull,103017ull,113805ull,116005ull,119333ull,124713ull,128977ull,131517ull,146585ull,136121ull,147597ull,150825ull,84061ull,84621ull,86773ull,115489ull,+ 140041ull,141993ull,97061ull,98261ull,101869ull,110265ull,127225ull,118229ull,80785ull,89061ull,94109ull,95977ull,98417ull,118473ull,119205ull,130665ull,131353ull,149713ull,154585ull,154913ull,155745ull,81453ull,124601ull,149201ull,154337ull,99205ull,80409ull,82793ull,94137ull,94461ull,104037ull,108553ull,+ 116537ull,121097ull,136177ull,147953ull,163381ull,104993ull,153785ull,84517ull,105965ull,106445ull,111877ull,113265ull,118821ull,120165ull,123309ull,128065ull,156025ull,83381ull,100537ull,154081ull,82093ull,95333ull,112553ull,146601ull,97837ull,99601ull,106589ull,118301ull,154137ull,84133ull,86077ull,94613ull,+ 104525ull,105785ull,107169ull,111509ull,118809ull,120713ull,130533ull,140093ull,140165ull,149297ull,154505ull,85245ull,113385ull,86133ull,116545ull,119393ull,137193ull,154253ull,160093ull,162429ull,106077ull,112429ull,133025ull,125741ull,126081ull,127561ull,117505ull,115301ull,142689ull,80641ull,134361ull,84201ull,+ 83997ull,96921ull,101197ull,127833ull,93717ull,111737ull,105169ull,146669ull,139569ull,153909ull,140845ull,97101ull,83201ull,87809ull,0ull,0ull,90473ull,0ull,104913ull,0ull,0ull,83833ull,117929ull,121641ull,124145ull,124281ull,124309ull,124477ull,154969ull,127737ull,130805ull,0ull,+ 137289ull,0ull,142305ull,0ull,0ull,147681ull,148469ull,0ull,0ull,0ull,156605ull,156657ull,156833ull,161489ull,148345ull,154333ull,81593ull,82845ull,83253ull,84773ull,84881ull,85317ull,87669ull,88089ull,88481ull,90369ull,90785ull,94609ull,94649ull,98897ull,99745ull,99897ull,+ 100297ull,103741ull,104329ull,105029ull,107029ull,112093ull,112745ull,113801ull,116153ull,116909ull,118921ull,123461ull,124153ull,124197ull,124193ull,124225ull,124249ull,124277ull,124469ull,124473ull,125185ull,125445ull,126721ull,128977ull,129061ull,129285ull,130505ull,131093ull,133045ull,133605ull,133605ull,135517ull,+ 140353ull,140889ull,142341ull,142565ull,144205ull,144417ull,147161ull,147681ull,154509ull,155645ull,155885ull,98773ull,592825ull,133217ull,0ull,0ull,80025ull,83669ull,83361ull,81409ull,83221ull,83457ull,84765ull,84969ull,87669ull,87381ull,87653ull,87945ull,90473ull,90829ull,91409ull,91473ull,+ 92553ull,93345ull,97097ull,97125ull,97701ull,97973ull,99169ull,99641ull,99361ull,99897ull,99713ull,100297ull,100561ull,102161ull,102513ull,102729ull,103769ull,104913ull,105565ull,105581ull,105817ull,110053ull,110313ull,111877ull,113517ull,113453ull,113801ull,114809ull,116153ull,122525ull,116949ull,117437ull,+ 117929ull,119237ull,119833ull,120045ull,120949ull,120957ull,121641ull,121709ull,121809ull,122153ull,122113ull,123697ull,125637ull,126721ull,127469ull,128365ull,128977ull,130297ull,131093ull,134473ull,135101ull,138725ull,140549ull,140825ull,140889ull,142077ull,142305ull,142125ull,142341ull,142329ull,142261ull,142565ull,+ 142889ull,144417ull,146657ull,147913ull,149093ull,149977ull,154097ull,154509ull,154969ull,155501ull,155645ull,155693ull,155885ull,158793ull,163441ull,565545ull,565521ull,577365ull,61045ull,65633ull,65765ull,608549ull,619329ull,654157ull,163085ull,163385ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,12247373670ull,0ull,12272539594ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,12356425638ull,12364814246ull,12356676902ull,12365065510ull,12272539458ull,12280928066ull,12314482498ull,12314482502ull,12314482506ull,12314482510ull,12314482514ull,12314482518ull,12314482522ull,0ull,12314482530ull,12314482534ull,12314482538ull,12314482542ull,12314482546ull,0ull,12314482554ull,0ull,+ 12314482562ull,12314482566ull,0ull,12314482574ull,12314482578ull,0ull,12314482586ull,12314482590ull,12314482594ull,12314482598ull,12314482602ull,12289316694ull,12339648326ull,12339648366ull,12339648402ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,6501439306ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,6501439338ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,585676112486ull,0ull,585676112494ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,585676112534ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,586590471366ull,586590471370ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,591078378782ull,591288093982ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,592244395530ull,0ull,592126955026ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,592185675310ull,0ull,0ull,592244395586ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,592185675530ull,0ull,592101789450ull,592244395786ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,594266051302ull,594182165222ull,0ull,594291217126ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,596321261282ull,596321261286ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,603845846230ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,758313747578ull,758406022266ull,758322136186ull,758322136230ull,758330524794ull,758322136198ull,758322136202ull,758330524806ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,784695932318ull,784695932302ull,784695932326ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,999427622238ull,999427622242ull,+ 999503119742ull,999511508350ull,999519896958ull,999528285566ull,999536674174ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,999427622630ull,999427622634ull,999503120110ull,999503120114ull,999511508718ull,+ 999511508722ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+ 80117ull,80097ull,80133ull,525449ull,81281ull,81593ull,81645ull,81929ull,82409ull,82533ull,82845ull,82749ull,53881ull,530665ull,83253ull,83281ull,83345ull,83421ull,529521ull,53989ull,83357ull,83509ull,529709ull,83549ull,83601ull,80689ull,83633ull,83669ull,673661ull,83925ull,83981ull,54141ull,+ 84205ull,84249ull,84425ull,84445ull,54357ull,84765ull,84773ull,84881ull,84969ull,85013ull,85017ull,85085ull,85285ull,85317ull,85353ull,85453ull,85493ull,85501ull,85501ull,85501ull,534705ull,115137ull,85801ull,85885ull,535949ull,85933ull,85957ull,86041ull,86649ull,86241ull,86305ull,86433ull,+ 86665ull,87001ull,87105ull,87373ull,87437ull,87569ull,87569ull,87653ull,87725ull,87757ull,87817ull,89177ull,88089ull,89181ull,88389ull,88529ull,83997ull,91065ull,89913ull,90065ull,90165ull,89645ull,90313ull,90309ull,90801ull,545681ull,91081ull,91101ull,91161ull,91241ull,91273ull,91529ull,+ 547489ull,547753ull,92081ull,92269ull,92317ull,92001ull,92569ull,56249ull,56305ull,93217ull,93433ull,93433ull,550689ull,93965ull,94049ull,94109ull,94157ull,552033ull,94205ull,94233ull,97613ull,94345ull,56837ull,94593ull,94649ull,94977ull,94773ull,554897ull,95501ull,554905ull,95673ull,95661ull,+ 95729ull,96133ull,96137ull,57533ull,96245ull,96417ull,96501ull,96677ull,57737ull,558605ull,57841ull,96961ull,96973ull,96985ull,97065ull,691785ull,97273ull,560325ull,560325ull,133125ull,97417ull,97417ull,58141ull,576225ull,624489ull,97673ull,97709ull,58253ull,97897ull,98101ull,98141ull,98277ull,+ 98821ull,58601ull,58481ull,98897ull,564049ull,99101ull,99617ull,99633ull,99641ull,99633ull,99817ull,99897ull,100041ull,99985ull,100029ull,100217ull,100297ull,100313ull,100417ull,100461ull,100725ull,101061ull,101201ull,101697ull,568369ull,101621ull,101361ull,101793ull,101901ull,102289ull,569285ull,102537ull,+ 102165ull,102053ull,59577ull,102821ull,102905ull,103029ull,102877ull,59825ull,103741ull,103857ull,573481ull,104333ull,105441ull,104741ull,60517ull,105029ull,60449ull,60305ull,83529ull,83541ull,105473ull,105073ull,131765ull,69477ull,105565ull,105581ull,105605ull,105849ull,105805ull,577293ull,60709ull,106473ull,+ 106005ull,106825ull,107029ull,577973ull,107065ull,106621ull,107601ull,61045ull,107785ull,108173ull,108457ull,109217ull,580237ull,109421ull,61537ull,109701ull,582301ull,109905ull,61753ull,110025ull,110205ull,110313ull,110317ull,584245ull,554029ull,584681ull,110905ull,586481ull,111357ull,111413ull,111005ull,111705ull,+ 111865ull,112093ull,111877ull,112037ull,112097ull,112149ull,586873ull,111825ull,112829ull,113081ull,62669ull,113453ull,113437ull,588613ull,112613ull,114105ull,589177ull,589369ull,114457ull,114917ull,114809ull,114797ull,63065ull,114985ull,115189ull,115165ull,115381ull,529557ull,115989ull,592269ull,116337ull,593581ull,+ 116897ull,116949ull,117057ull,596001ull,117249ull,117333ull,597205ull,598097ull,118249ull,118317ull,64177ull,118421ull,64225ull,64225ull,119069ull,119153ull,119237ull,119317ull,119593ull,64621ull,119953ull,602329ull,120057ull,602697ull,120257ull,558717ull,120897ull,605829ull,605921ull,606481ull,65521ull,65569ull,+ 121809ull,607181ull,607177ull,607333ull,607437ull,121977ull,121981ull,121981ull,122153ull,65765ull,122413ull,65817ull,66137ull,610421ull,123193ull,123441ull,123697ull,66445ull,612505ull,124249ull,612969ull,613141ull,124477ull,124845ull,66749ull,125185ull,125225ull,125245ull,615921ull,617117ull,617117ull,125881ull,+ 67593ull,618157ull,126745ull,126757ull,67741ull,619009ull,127817ull,68225ull,127905ull,127885ull,128001ull,622105ull,128397ull,68613ull,128797ull,129033ull,129301ull,68817ull,624801ull,624925ull,68965ull,625509ull,130537ull,625913ull,130645ull,131049ull,131093ull,627561ull,627853ull,131457ull,628385ull,131521ull,+ 576893ull,69461ull,131785ull,132109ull,69677ull,132345ull,92885ull,630429ull,630485ull,577101ull,577137ull,133125ull,133137ull,147065ull,70061ull,133701ull,133677ull,133749ull,84685ull,133829ull,133837ull,133877ull,134041ull,634097ull,134037ull,134261ull,134541ull,134837ull,134285ull,134901ull,135069ull,135517ull,+ 134477ull,134953ull,134961ull,135025ull,635097ull,636333ull,635733ull,70829ull,136133ull,136141ull,136281ull,642857ull,136593ull,638129ull,71029ull,71045ull,638661ull,639817ull,71085ull,137537ull,137585ull,137629ull,137637ull,137893ull,137761ull,138297ull,138121ull,138725ull,138401ull,138669ull,138777ull,71517ull,+ 139141ull,139269ull,71653ull,139649ull,139661ull,645533ull,140125ull,140153ull,71893ull,140265ull,53997ull,647865ull,648601ull,72441ull,72477ull,141953ull,142261ull,142889ull,143701ull,651937ull,144045ull,144133ull,144493ull,144861ull,654525ull,532497ull,145197ull,145137ull,145345ull,533369ull,146257ull,146657ull,+ 661321ull,661429ull,148049ull,148421ull,148549ull,662713ull,148589ull,149729ull,150365ull,150369ull,150001ull,151525ull,151637ull,667625ull,153133ull,75349ull,153309ull,669149ull,75673ull,154381ull,95945ull,154765ull,673045ull,673897ull,76217ull,76249ull,155521ull,675881ull,76489ull,676441ull,155693ull,155693ull,+ 155813ull,677593ull,156553ull,77005ull,156837ull,157341ull,157449ull,157689ull,77625ull,683201ull,158793ull,160001ull,160757ull,78649ull,78773ull,161181ull,688953ull,78817ull,689173ull,690233ull,690757ull,162541ull,79193ull,162789ull,162809ull,162837ull,162877ull,162905ull,163053ull,694273ull,0ull,0ull,+ 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,+};++KBTS_INLINE kbts_u64 kbts__GetUnicodeDecomposition(kbts_u32 Codepoint)+{+ return (Codepoint < 1114110) ? kbts__UnicodeDecomposition_Data[((kbts_un)kbts__UnicodeDecomposition_PageIndices[Codepoint/64] * 64) | (Codepoint & 63)] : 0;+}++static kbts_u8 kbts__UnicodeWordBreakClass_PageIndices[8703] = {+ 0,1,2,2,2,3,4,5,2,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,+ 29,30,2,2,31,32,33,34,35,2,2,2,36,37,38,39,40,41,42,43,44,45,46,47,48,49,2,50,2,2,51,52,+ 53,54,55,56,57,57,58,59,57,60,57,61,62,63,64,65,57,57,66,57,57,57,67,57,2,68,69,70,71,57,57,57,+ 72,73,74,75,57,76,77,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 2,2,2,2,2,2,2,2,2,78,2,2,79,80,81,82,83,84,85,86,87,88,89,90,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,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,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,91,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,92,93,2,2,94,95,96,97,98,99,+ 100,101,102,103,57,104,105,106,2,107,108,109,2,2,110,111,112,113,114,115,116,117,118,119,120,121,122,123,57,124,125,126,+ 127,128,129,130,131,132,133,134,135,136,57,137,138,139,140,57,141,142,143,144,145,146,57,147,148,149,150,151,57,152,153,154,+ 2,2,2,2,2,2,2,155,156,2,157,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,158,+ 2,2,2,2,2,2,2,2,159,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,101,2,2,2,2,160,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,161,57,57,57,57,57,57,57,57,57,57,57,57,57,2,2,2,2,162,163,164,165,57,57,166,57,167,57,168,169,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,170,+ 171,57,172,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,173,174,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,175,57,57,57,57,176,57,+ 57,57,177,178,179,57,57,57,180,181,182,2,2,183,184,185,57,57,57,57,186,187,57,57,57,57,57,57,57,57,188,57,+ 189,190,191,57,57,192,57,57,57,193,57,194,57,57,57,195,2,196,197,57,57,57,57,57,57,57,57,57,198,199,57,57,+ 200,200,201,202,203,200,200,204,200,200,205,200,206,200,207,208,209,210,211,200,200,200,57,175,200,200,200,200,200,200,200,212,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 213,57,214,215,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+};++static kbts_u8 kbts__UnicodeWordBreakClass_Data[27648] = {+ 0,0,0,0,0,0,0,0,0,0,3,4,4,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20,0,14,0,0,0,0,13,0,0,0,0,17,0,15,0,18,18,18,18,18,18,18,18,18,18,16,17,0,0,0,0,+ 0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,19,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,+ 0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,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,11,0,0,8,1,0,0,0,0,0,0,11,0,16,0,0,11,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,11,11,11,11,11,0,11,11,0,0,11,11,11,11,17,11,+ 0,0,0,0,0,0,11,16,11,11,11,0,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,+ 11,11,0,5,5,5,5,5,5,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,11,11,11,11,0,11,16,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,17,11,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,5,+ 0,5,5,0,5,5,0,5,0,0,0,0,0,0,0,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,0,0,0,0,10,10,10,10,11,16,0,0,0,0,0,0,0,0,0,0,0,+ 18,18,18,18,18,18,0,0,0,0,0,0,17,17,0,0,5,5,5,5,5,5,5,5,5,5,5,0,8,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,18,18,18,18,18,18,18,18,18,18,0,18,17,0,11,11,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,5,5,5,5,5,5,5,18,0,5,5,5,5,5,5,11,11,5,5,0,5,5,5,5,11,11,18,18,18,18,18,18,18,18,18,18,11,11,11,0,0,11,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,5,5,5,5,5,5,5,5,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 18,18,18,18,18,18,18,18,18,18,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,11,11,0,0,17,0,11,0,0,5,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,11,5,5,5,5,5,5,5,5,5,11,5,5,5,11,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,0,18,18,0,0,0,0,0,5,5,5,5,5,5,5,5,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,18,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,11,5,5,+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,11,5,5,5,5,5,5,5,11,11,11,11,11,11,11,11,11,11,5,5,0,0,18,18,18,18,18,18,18,18,18,18,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,5,5,5,0,11,11,11,11,11,11,11,11,0,0,11,11,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,0,11,0,0,0,11,11,11,11,0,0,5,11,5,5,+ 5,5,5,5,5,0,0,5,5,0,0,5,5,5,11,0,0,0,0,0,0,0,0,5,0,0,0,0,11,11,0,11,11,11,5,5,0,0,18,18,18,18,18,18,18,18,18,18,11,11,0,0,0,0,0,0,0,0,0,0,11,0,5,0,+ 0,5,5,5,0,11,11,11,11,11,11,0,0,0,0,11,11,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,0,11,11,0,11,11,0,11,11,0,0,5,0,5,5,+ 5,5,5,0,0,0,0,5,5,0,0,5,5,5,0,0,0,5,0,0,0,0,0,0,0,11,11,11,11,0,11,0,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,5,5,11,11,11,5,0,0,0,0,0,0,0,0,0,0,+ 0,5,5,5,0,11,11,11,11,11,11,11,11,11,0,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,0,11,11,0,11,11,11,11,11,0,0,5,11,5,5,+ 5,5,5,5,5,5,0,5,5,5,0,5,5,5,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,5,5,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,11,5,5,5,5,5,5,+ 0,5,5,5,0,11,11,11,11,11,11,11,11,0,0,11,11,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,0,11,11,0,11,11,11,11,11,0,0,5,11,5,5,+ 5,5,5,5,5,0,0,5,5,0,0,5,5,5,0,0,0,0,0,0,0,5,5,5,0,0,0,0,11,11,0,11,11,11,5,5,0,0,18,18,18,18,18,18,18,18,18,18,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,5,11,0,11,11,11,11,11,11,0,0,0,11,11,11,0,11,11,11,11,0,0,0,11,11,0,11,0,11,11,0,0,0,11,11,0,0,0,11,11,11,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,5,5,+ 5,5,5,0,0,0,5,5,5,0,5,5,5,5,0,0,11,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 5,5,5,5,5,11,11,11,11,11,11,11,11,0,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,5,11,5,5,+ 5,5,5,5,5,0,5,5,5,0,5,5,5,5,0,0,0,0,0,0,0,5,5,0,11,11,11,0,0,11,0,0,11,11,5,5,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,5,5,5,0,11,11,11,11,11,11,11,11,0,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,0,0,5,11,5,5,+ 5,5,5,5,5,0,5,5,5,0,5,5,5,5,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,11,11,0,11,11,5,5,0,0,18,18,18,18,18,18,18,18,18,18,0,11,11,5,0,0,0,0,0,0,0,0,0,0,0,0,+ 5,5,5,5,11,11,11,11,11,11,11,11,11,0,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,11,5,5,+ 5,5,5,5,5,0,5,5,5,0,5,5,5,5,11,0,0,0,0,0,11,11,11,5,0,0,0,0,0,0,0,11,11,11,5,5,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,+ 0,5,5,5,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,0,11,0,0,+ 11,11,11,11,11,11,11,0,0,0,5,0,0,0,0,5,5,5,5,5,5,0,5,0,5,5,5,5,5,5,5,5,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,5,5,5,5,5,5,5,0,0,0,0,0,+ 0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,5,5,5,5,5,5,5,5,5,0,0,0,+ 0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,5,0,5,0,5,0,0,0,0,5,5,+ 11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,5,5,0,5,5,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,+ 0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,+ 18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,0,0,0,0,5,5,5,0,5,5,5,0,0,5,5,5,5,5,5,5,0,0,0,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,5,5,5,5,5,5,5,5,5,5,5,5,0,5,18,18,18,18,18,18,18,18,18,18,5,5,5,5,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,0,11,0,0,0,0,0,11,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,0,11,11,11,11,0,0,11,11,11,11,11,11,11,0,11,0,11,11,11,11,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,0,11,11,11,11,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,0,0,11,11,11,11,11,11,11,0,+ 11,0,11,11,11,11,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,11,11,11,11,11,11,0,0,+ 0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 20,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,5,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,5,5,5,8,5,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,+ 11,11,11,11,11,5,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,11,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,+ 0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,5,+ 18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 5,5,5,5,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,5,5,11,11,11,11,11,11,11,11,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,+ 5,5,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,5,11,11,18,18,18,18,18,18,18,18,18,18,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,+ 18,18,18,18,18,18,18,18,18,18,0,0,0,11,11,11,18,18,18,18,18,18,18,18,18,18,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,11,11,11,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,11,11,11,11,5,11,11,11,11,11,11,5,11,11,5,5,5,11,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,11,11,11,11,11,11,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,0,0,11,11,11,11,11,11,0,0,11,11,11,11,11,11,11,11,0,11,0,11,0,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,0,11,0,+ 0,0,11,11,11,0,11,11,11,11,11,11,11,0,0,0,11,11,11,11,0,0,11,11,11,11,11,11,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,11,11,11,0,11,11,11,11,11,11,11,0,0,0,+ 20,20,20,20,20,20,20,0,20,20,20,0,5,6,8,8,0,0,0,0,0,0,0,0,15,15,0,0,0,0,0,0,0,0,0,0,15,0,0,16,4,4,8,8,8,8,8,19,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,19,+ 19,0,0,0,17,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,19,0,0,0,0,0,0,0,0,0,0,20,8,8,8,8,8,0,8,8,8,8,8,8,8,8,8,8,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,11,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,11,0,0,0,0,11,0,0,11,11,11,11,11,11,11,11,11,11,0,11,0,0,0,11,11,11,11,11,0,0,0,0,1,0,11,0,11,0,11,0,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,12,0,0,11,11,11,11,+ 0,0,0,0,0,11,11,11,11,11,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,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,0,0,0,0,1,1,1,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,+ 11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,+ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,+ 1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,1,0,0,1,0,0,0,0,1,0,1,0,0,0,0,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,11,11,11,11,5,5,5,11,11,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,0,0,0,0,0,11,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,0,+ 11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,1,9,9,9,9,9,0,0,0,0,0,11,11,1,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,9,9,0,0,0,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,+ 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,0,9,9,9,9,+ 0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,0,+ 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,+ 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,18,18,18,18,18,18,18,18,18,18,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,0,5,5,5,5,5,5,5,5,5,5,0,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,11,11,0,11,0,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,5,11,11,11,5,11,11,11,11,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,+ 5,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,11,11,11,11,11,11,0,0,0,11,0,11,11,5,+ 18,18,18,18,18,18,18,18,18,18,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,+ 5,5,5,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,+ 11,11,11,5,11,11,11,11,11,11,11,11,5,5,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,5,5,5,0,0,5,5,0,0,0,0,0,5,5,+ 0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,0,0,11,11,11,5,5,0,0,0,0,0,0,0,0,0,+ 0,11,11,11,11,11,11,0,0,11,11,11,11,11,11,0,0,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,0,5,5,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,+ 11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,0,0,0,0,0,10,5,10,10,10,10,10,10,10,10,10,10,0,10,10,10,10,10,10,10,10,10,10,10,10,10,0,10,10,10,10,10,0,10,0,+ 10,10,0,10,10,0,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,19,19,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,19,19,19,17,0,15,0,17,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,8,+ 0,0,0,0,0,0,0,15,0,0,0,0,17,0,15,0,18,18,18,18,18,18,18,18,18,18,16,17,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,19,+ 0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,+ 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,5,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,+ 0,0,11,11,11,11,11,11,0,0,11,11,11,11,11,11,0,0,11,11,11,11,11,11,0,0,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,8,8,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,0,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,0,0,0,0,11,11,11,11,11,11,11,11,0,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,0,11,11,0,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,0,11,11,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,0,0,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,0,0,0,11,0,0,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,11,11,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,5,5,5,0,5,5,0,0,0,0,0,5,5,5,5,11,11,11,11,0,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,5,5,5,0,0,0,0,5,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,0,0,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,+ 18,18,18,18,18,18,18,18,18,18,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,5,5,5,5,5,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,5,5,0,0,0,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,+ 5,5,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,+ 5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,5,11,11,5,5,11,0,0,0,0,0,0,0,0,0,5,+ 5,5,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,0,0,18,0,0,+ 0,0,5,0,0,0,0,0,0,0,0,0,0,18,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,+ 5,5,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,18,18,18,18,18,18,18,18,18,18,+ 0,0,0,0,11,5,5,11,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,0,0,11,0,0,0,0,0,0,0,0,0,+ 5,5,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,11,11,11,11,0,0,0,0,5,5,5,5,0,5,5,18,18,18,18,18,18,18,18,18,18,11,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,5,11,+ 11,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,0,11,0,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,+ 5,5,5,5,0,11,11,11,11,11,11,11,11,0,0,11,11,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,0,11,11,0,11,11,11,11,11,0,5,5,11,5,5,+ 5,5,5,5,5,0,0,5,5,0,0,5,5,5,0,0,11,0,0,0,0,0,0,5,0,0,0,0,0,11,11,11,11,11,5,5,0,0,5,5,5,5,5,5,5,0,0,0,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,0,11,0,0,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,5,5,5,5,5,5,5,5,+ 5,0,5,0,0,5,0,5,5,5,5,0,5,5,5,5,5,11,5,11,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,5,5,5,5,11,11,11,11,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,5,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,5,11,11,0,11,0,0,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,0,0,5,5,5,5,5,5,5,5,+ 5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,5,11,0,0,0,0,0,0,0,+ 18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,+ 11,11,11,11,11,11,11,0,0,11,0,0,11,11,11,11,11,11,11,11,0,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,0,5,5,0,0,5,5,5,5,11,+ 5,11,5,5,0,0,0,0,0,0,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,0,0,5,5,5,5,5,5,5,11,0,11,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,5,5,5,5,5,5,5,5,5,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,11,5,5,5,5,0,+ 0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,11,5,5,5,5,5,5,5,5,5,5,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,0,5,5,5,5,5,5,5,5,+ 11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,0,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,0,0,0,5,0,5,5,0,5,+ 5,5,5,5,5,5,11,5,0,0,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,11,11,11,11,11,11,0,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,0,5,5,0,5,5,5,5,5,11,0,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,0,0,0,0,0,0,0,0,0,+ 5,5,11,5,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,0,0,0,5,5,+ 5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,+ 5,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,+ 18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,5,11,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,5,5,5,5,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,0,11,5,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9,9,9,0,9,9,9,9,9,9,9,0,9,9,0,+ 9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,+ 11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,0,0,0,5,5,0,8,8,8,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,0,0,0,5,5,5,5,5,5,8,8,8,8,8,8,8,8,5,5,5,5,5,+ 5,5,5,0,0,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,0,0,11,0,0,11,11,0,0,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,0,11,0,11,11,11,+ 11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,0,11,11,11,11,0,0,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,0,+ 11,11,11,11,11,0,11,0,0,0,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,0,11,11,11,11,11,11,11,11,0,0,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,5,5,5,5,5,+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 5,5,5,5,5,5,5,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,5,5,5,5,5,5,5,0,5,5,0,5,5,5,5,5,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,5,5,5,5,5,5,5,11,11,11,11,11,11,11,0,0,+ 18,18,18,18,18,18,18,18,18,18,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,11,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,0,11,11,11,11,0,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,5,5,5,5,5,5,5,11,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,0,11,0,0,11,0,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,0,11,0,11,0,0,0,0,+ 0,0,11,0,0,0,0,11,0,11,0,11,0,11,11,11,0,11,11,0,11,0,0,11,0,11,0,11,0,11,0,11,0,11,11,0,11,0,0,11,11,11,11,0,11,11,11,11,11,11,11,0,11,11,11,11,0,11,11,11,11,0,11,0,+ 11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,11,11,11,0,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,1,1,1,1,12,12,11,11,11,11,11,11,11,11,11,11,11,11,12,12,+ 11,11,11,11,11,11,11,11,11,11,0,0,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,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,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,+ 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,+ 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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,5,5,5,5,5,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,+ 0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,+ 1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,+ 0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+};++KBTS_INLINE kbts_u8 kbts__GetUnicodeWordBreakClass(kbts_u32 Codepoint)+{+ return (Codepoint < 1114110) ? kbts__UnicodeWordBreakClass_Data[((kbts_un)kbts__UnicodeWordBreakClass_PageIndices[Codepoint/128] * 128) | (Codepoint & 127)] : 0;+}++static kbts_u8 kbts__UnicodeLineBreakClass_PageIndices[8703] = {+ 0,1,2,2,2,3,4,2,2,5,2,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,+ 27,28,29,30,2,2,31,2,32,2,2,2,2,33,34,35,36,37,38,39,40,41,42,43,44,45,2,46,2,2,2,47,+ 48,49,50,2,51,52,53,54,2,2,2,55,56,57,58,59,2,2,2,60,2,2,61,2,2,62,63,64,65,66,67,68,+ 69,70,71,72,73,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,+ 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,74,67,67,67,67,+ 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,+ 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,+ 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,+ 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,+ 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,+ 75,67,67,67,67,67,67,67,67,76,2,2,77,78,2,2,79,80,81,82,83,84,2,85,86,87,88,89,90,91,92,86,+ 87,88,89,90,91,92,86,87,88,89,90,91,92,86,87,88,89,90,91,92,86,87,88,89,90,91,92,86,87,88,89,90,+ 91,92,86,87,88,89,90,91,92,86,87,88,89,90,91,92,86,87,88,89,90,91,92,86,87,88,89,90,91,92,86,87,+ 88,89,90,91,92,86,87,88,89,90,91,92,86,87,88,93,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,+ 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,2,2,+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,67,67,67,67,95,2,2,2,96,97,98,99,100,101,+ 2,2,102,103,2,104,105,106,2,107,2,2,2,2,2,2,108,2,109,2,110,111,112,2,2,2,113,2,2,114,115,116,+ 117,118,119,120,121,122,123,124,125,126,2,127,128,129,130,2,131,132,133,134,135,136,137,138,139,140,141,142,2,143,144,145,+ 2,2,2,2,2,2,2,2,146,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,147,148,149,2,150,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,2,2,2,2,151,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,+ 2,2,152,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,153,154,155,2,2,2,156,2,2,157,158,159,+ 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,+ 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,160,67,67,67,67,67,67,161,161,161,162,163,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,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,2,2,2,2,2,2,2,2,164,+ 67,67,165,67,67,166,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,167,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,2,138,2,2,2,2,168,2,+ 2,2,169,170,171,2,172,2,2,2,2,2,2,2,2,173,2,2,2,2,174,175,2,2,2,2,2,2,2,2,2,2,+ 176,177,178,2,2,179,2,2,2,180,2,181,2,2,2,2,2,182,183,2,2,2,2,2,2,184,2,2,2,2,2,2,+ 185,186,2,187,188,189,190,191,192,193,194,195,196,197,198,199,2,2,200,201,202,203,2,138,189,189,189,189,189,189,189,204,+ 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,+ 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,+ 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,+ 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,+ 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,+ 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,+ 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,+ 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,+ 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,+ 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,+ 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,+ 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,+ 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,+ 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,+ 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,+ 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,205,+ 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,+ 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,+ 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,+ 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,+ 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,+ 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,+ 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,+ 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,+ 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,+ 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,+ 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,+ 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,+ 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,+ 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,+ 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,+ 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,205,+ 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+ 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+ 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+ 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+ 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+ 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+ 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+ 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+ 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+ 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+ 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,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,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,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,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,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,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,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,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,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,+ 206,2,207,208,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,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,+ 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+ 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+ 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+ 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,2,+};++static kbts_u8 kbts__UnicodeLineBreakClass_Data[26752] = {+ 63,63,63,63,63,63,63,63,63,19,5,3,3,4,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,7,16,23,37,40,48,37,23,21,14,37,40,26,31,26,18,39,39,39,39,39,39,39,39,39,39,26,26,37,37,37,16,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,21,40,14,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,21,19,12,37,63,+ 63,63,63,63,63,6,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,10,21,48,40,40,40,37,37,37,37,37,24,37,19,37,37,48,40,37,37,35,37,37,37,37,37,37,25,37,37,37,21,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,35,37,37,37,35,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,35,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,+ 63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,10,63,63,63,63,63,63,63,63,63,63,63,63,10,10,10,10,10,10,10,63,63,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,26,37,+ 37,37,37,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,26,19,37,37,37,37,40,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,19,63,+ 37,63,63,37,63,63,16,63,37,37,37,37,37,37,37,37,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,37,37,37,37,36,36,36,36,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 39,39,39,39,39,39,37,37,37,48,48,48,26,26,37,37,63,63,63,63,63,63,63,63,63,63,63,16,63,16,16,16,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,39,39,39,39,39,39,39,39,39,39,48,39,39,37,37,37,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,16,37,63,63,63,63,63,63,63,39,37,63,63,63,63,63,63,37,37,63,63,37,63,63,63,63,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,+ 63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,37,37,37,37,26,16,37,37,37,63,40,40,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,37,63,63,63,63,63,63,63,63,63,37,63,63,63,37,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,39,39,37,37,37,37,37,63,63,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,39,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,+ 63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,37,63,63,+ 63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,37,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,63,63,19,19,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,37,63,63,+ 63,63,63,63,63,37,37,63,63,37,37,63,63,63,37,37,37,37,37,37,37,37,37,63,37,37,37,37,37,37,37,37,37,37,63,63,37,37,39,39,39,39,39,39,39,39,39,39,37,37,48,48,37,37,37,37,37,48,37,40,37,37,63,37,+ 37,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,37,63,63,+ 63,63,63,37,37,37,37,63,63,37,37,63,63,63,37,37,37,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,63,63,37,37,37,63,37,37,37,37,37,37,37,37,37,37,+ 37,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,37,63,63,+ 63,63,63,63,63,63,37,63,63,63,37,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,37,37,39,39,39,39,39,39,39,39,39,39,37,40,37,37,37,37,37,37,37,37,63,63,63,63,63,63,+ 37,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,37,63,63,+ 63,63,63,63,63,37,37,63,63,37,37,63,63,63,37,37,37,37,37,37,37,63,63,63,37,37,37,37,37,37,37,37,37,37,63,63,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,+ 63,63,63,37,37,37,63,63,63,37,63,63,63,63,37,37,37,37,37,37,37,37,37,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,40,37,37,37,37,37,37,+ 63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,37,63,63,+ 63,63,63,63,63,37,63,63,63,37,63,63,63,63,37,37,37,37,37,37,37,63,63,37,37,37,37,37,37,37,37,37,37,37,63,63,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,35,37,37,37,37,37,37,37,37,+ 37,63,63,63,35,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,37,63,63,+ 63,63,63,63,63,37,63,63,63,37,63,63,63,63,37,37,37,37,37,37,37,63,63,37,37,37,37,37,37,37,37,37,37,37,63,63,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,63,37,37,37,37,37,37,37,37,37,37,37,37,+ 63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,37,63,63,+ 63,63,63,63,63,37,63,63,63,37,63,63,63,63,37,37,37,37,37,37,37,37,37,63,37,37,37,37,37,37,37,37,37,37,63,63,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,48,37,37,37,37,37,37,+ 37,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,63,37,37,37,37,63,63,63,63,63,63,37,63,37,63,63,63,63,63,63,63,63,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,63,63,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,40,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,19,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,35,35,35,35,37,35,35,10,35,35,19,10,16,16,16,16,16,10,37,16,37,37,37,63,63,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,19,63,37,63,37,63,21,12,21,12,63,63,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,19,+ 63,63,63,63,63,19,63,63,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,37,19,19,+ 37,37,37,37,37,37,63,37,37,37,37,37,37,37,37,37,35,35,19,35,37,37,37,37,37,10,10,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 39,39,39,39,39,39,39,39,39,39,19,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,+ 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,+ 51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,+ 52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,37,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,21,12,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,19,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,19,19,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,19,27,37,19,37,19,40,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,16,16,19,19,35,37,16,16,37,63,63,63,10,63,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,+ 37,37,37,37,16,16,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,+ 39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,+ 63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 63,63,63,63,63,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,63,63,63,63,63,63,63,63,63,63,63,63,+ 63,63,63,63,60,56,56,56,56,56,56,56,56,37,19,19,58,58,58,58,58,58,58,58,58,58,19,19,42,19,19,19,19,42,42,42,42,42,42,42,42,42,42,63,63,63,63,63,63,63,63,63,42,42,42,42,42,42,42,42,42,19,19,19,+ 63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,+ 58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,63,63,63,63,63,63,63,63,63,63,63,63,59,59,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,37,37,37,19,19,19,19,19,+ 39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,19,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,63,37,37,37,37,37,37,63,37,37,63,63,63,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 63,63,63,63,63,63,63,63,63,63,63,63,63,10,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,10,63,63,63,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,35,37,37,+ 19,19,19,19,19,19,19,10,19,19,19,8,63,64,63,63,32,10,19,19,29,37,37,37,24,25,21,24,24,25,21,24,37,37,37,37,33,33,33,19,3,3,63,63,63,63,63,10,48,48,48,48,48,48,48,48,37,24,25,37,27,27,37,37,+ 37,37,37,37,26,21,12,27,27,27,37,37,37,37,37,37,37,37,37,37,37,37,19,48,19,19,19,19,37,19,19,19,9,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,21,12,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,21,12,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,40,40,40,40,40,40,40,48,40,41,40,40,40,40,40,40,40,40,40,40,40,40,48,40,40,40,40,48,40,40,48,40,+ 48,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,48,37,37,37,37,37,48,37,37,37,37,37,37,37,37,37,37,37,37,40,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,40,40,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,33,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,21,12,21,12,37,37,37,37,37,37,37,37,37,37,37,37,37,37,43,43,37,37,37,37,37,37,37,37,37,37,37,37,37,22,13,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,38,38,38,38,37,37,37,43,42,42,43,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,57,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,38,38,37,+ 42,42,42,42,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,43,43,37,37,42,37,42,42,42,45,42,42,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,38,38,38,38,38,38,38,38,37,42,42,42,37,37,37,37,+ 37,37,37,37,37,37,37,37,38,38,38,38,38,38,38,38,38,38,38,38,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,42,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,43,+ 37,37,37,37,37,37,37,37,37,37,38,38,38,38,38,38,37,37,37,38,37,37,37,37,37,37,37,37,37,37,37,37,37,38,37,37,37,37,37,37,37,37,38,38,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,43,43,42,+ 42,42,42,42,43,43,42,42,42,37,37,37,37,42,38,42,42,42,37,42,43,37,37,37,42,42,37,37,42,37,37,42,42,42,37,37,37,37,37,37,37,37,43,37,37,37,37,37,37,42,43,43,42,43,37,42,42,45,43,37,37,43,42,42,+ 42,42,42,42,42,38,37,37,42,42,46,46,45,45,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,38,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,38,37,38,37,37,37,37,38,38,38,37,38,37,37,37,23,23,23,23,23,23,37,16,16,42,37,37,37,21,12,21,12,21,12,21,12,21,12,21,12,21,12,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,38,38,38,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,38,37,37,37,37,37,37,37,37,37,37,37,37,37,37,38,+ 37,37,37,37,37,21,12,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,21,12,21,12,21,12,21,12,21,12,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,21,12,21,12,21,12,21,12,21,12,21,12,21,12,21,12,21,12,21,12,21,12,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,21,12,21,12,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,21,12,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,38,38,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,38,37,37,37,37,38,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,37,37,37,37,37,37,37,16,19,19,19,37,16,19,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,+ 23,23,24,25,24,25,23,23,23,24,25,23,24,25,19,19,19,19,19,19,19,19,37,19,21,19,37,37,24,25,37,37,24,25,21,12,21,12,21,12,21,12,19,19,19,19,16,37,19,19,37,19,19,37,37,37,37,37,29,29,19,19,19,37,+ 19,19,21,19,19,19,19,19,19,19,19,37,19,37,19,19,37,37,37,16,16,21,14,21,14,21,14,21,14,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,37,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,+ 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,37,37,37,37,37,37,37,37,37,37,37,37,+ 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,+ 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,+ 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,+ 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,+ 20,13,13,43,43,28,43,43,22,13,22,13,22,13,22,13,22,13,43,43,22,13,22,13,22,13,22,13,28,22,13,13,43,43,43,43,43,43,43,43,43,43,63,63,63,63,63,63,43,43,43,43,43,63,43,43,43,43,43,28,28,43,43,42,+ 37,65,43,65,43,65,43,65,43,65,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,65,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,+ 43,43,43,65,43,65,43,65,43,43,43,43,43,43,65,43,43,43,43,43,43,65,65,37,37,63,63,28,28,28,28,43,28,65,43,65,43,65,43,65,43,65,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,+ 43,43,43,65,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,65,43,65,43,65,43,43,43,43,43,43,65,43,43,43,43,43,43,65,65,43,43,43,43,28,65,28,28,43,+ 37,37,37,37,37,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,37,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,+ 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,+ 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,37,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,+ 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,37,37,37,37,37,37,37,37,37,43,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,+ 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,37,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,+ 43,43,43,43,43,43,43,43,37,37,37,37,37,37,37,37,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,+ 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,+ 38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,+ 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,28,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,+ 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,+ 43,43,43,43,43,43,43,43,43,43,43,43,43,37,37,37,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,+ 43,43,43,43,43,43,43,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,19,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,19,16,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,37,63,63,63,63,63,63,63,63,63,63,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,37,19,19,19,19,19,37,37,37,37,37,37,37,37,+ 37,37,63,37,37,37,63,37,37,37,37,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,37,37,37,37,63,37,37,37,37,37,37,37,37,37,37,37,48,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,35,35,16,16,37,37,37,37,37,37,37,37,+ 63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,+ 63,63,63,63,63,63,37,37,37,37,37,37,37,37,19,19,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,35,37,37,63,+ 39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,19,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,37,37,37,+ 63,63,63,63,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,63,63,63,63,63,63,63,63,63,63,63,63,63,+ 60,42,42,42,42,42,42,19,19,19,42,42,42,42,37,19,58,58,58,58,58,58,58,58,58,58,37,37,37,37,42,42,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,+ 58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,63,63,63,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,+ 19,19,19,63,19,19,19,19,19,19,19,19,63,63,37,37,58,58,58,58,58,58,58,58,58,58,37,37,42,19,19,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,19,19,37,37,37,63,63,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,19,63,63,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,+ 53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,+ 54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,+ 54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,+ 54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,+ 54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,+ 54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,+ 54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,+ 53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,+ 54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,+ 54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,+ 54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,+ 54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,+ 54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,+ 54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,+ 54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,37,37,37,37,37,37,37,37,37,37,37,37,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,+ 51,51,51,51,51,51,51,37,37,37,37,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,37,37,37,37,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,36,63,36,36,36,36,36,36,36,36,36,36,37,36,36,36,36,36,36,36,36,36,36,36,36,36,37,36,36,36,36,36,37,36,37,+ 36,36,37,36,36,37,36,36,36,36,36,36,36,36,36,36,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,12,21,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,48,37,37,37,+ 63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,13,13,13,28,28,17,17,22,13,34,37,37,37,37,37,37,10,63,10,63,10,63,10,10,63,10,63,10,63,10,10,63,43,43,43,43,43,22,13,22,13,22,13,22,13,22,13,22,+ 13,22,13,22,13,43,43,22,13,43,43,43,43,43,43,43,13,43,13,37,28,28,17,17,43,22,13,22,13,22,13,43,43,43,43,43,43,43,43,37,43,41,49,43,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,9,+ 37,17,43,43,41,49,43,43,22,13,43,43,13,43,13,43,43,43,43,43,43,43,43,43,43,43,28,28,43,43,43,17,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,22,43,13,43,43,+ 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,22,43,13,43,22,13,13,22,13,13,28,43,65,65,65,65,65,65,65,65,65,65,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,+ 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,28,28,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,37,+ 37,37,43,43,43,43,43,43,37,37,43,43,43,43,43,43,37,37,43,43,43,43,43,43,37,37,43,43,43,37,37,37,49,41,43,43,43,41,41,37,38,38,38,38,38,38,38,37,37,37,37,37,37,37,37,37,37,63,63,63,30,37,37,37,+ 19,19,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,63,63,63,37,63,63,37,37,37,37,37,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,37,37,37,37,63,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,19,19,19,19,19,19,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,37,37,37,37,37,37,37,37,37,19,19,19,19,19,19,33,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,19,19,19,19,19,19,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,+ 39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 63,63,63,55,55,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,63,63,63,63,63,63,63,63,+ 63,63,63,63,63,63,60,19,19,42,42,42,42,42,37,37,37,37,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,58,58,58,58,58,58,58,58,58,58,63,56,56,63,63,56,37,37,37,37,37,37,37,37,37,10,+ 63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,37,37,39,19,19,+ 19,19,63,37,37,37,37,37,37,37,37,37,37,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,+ 63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,37,39,39,39,39,39,39,39,39,39,39,+ 19,19,19,19,37,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,37,35,37,37,37,37,37,37,37,37,37,37,+ 63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,+ 63,37,37,37,37,19,19,37,19,63,63,63,63,37,63,63,39,39,39,39,39,39,39,39,39,39,37,35,37,19,19,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,19,19,37,19,19,37,63,37,+ 37,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,+ 63,63,63,63,37,56,56,56,56,56,56,56,56,37,37,56,56,37,37,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,37,56,56,56,56,56,56,56,37,56,56,37,56,56,56,56,56,37,63,63,19,63,63,+ 63,63,63,63,63,37,37,63,63,37,37,63,63,60,37,37,58,37,37,37,37,37,37,63,37,37,37,37,37,19,58,58,56,56,63,63,37,37,63,63,63,63,63,63,63,37,37,37,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,+ 58,58,58,58,58,58,58,58,58,58,37,58,37,37,58,37,58,58,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,37,42,63,63,63,63,63,63,63,63,+ 63,37,63,37,37,63,37,63,63,63,63,37,63,63,63,63,60,55,63,42,42,42,37,42,42,37,37,37,37,37,37,37,37,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,+ 63,63,63,63,63,63,63,37,37,37,37,19,19,19,19,37,39,39,39,39,39,39,39,39,39,39,19,19,37,37,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,+ 63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,37,37,63,63,63,63,63,63,63,63,+ 63,35,19,19,16,16,37,37,37,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,37,37,37,37,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,+ 63,19,19,37,37,37,37,37,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,35,35,35,35,35,35,35,35,35,35,35,35,35,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,+ 39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,19,19,19,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 56,56,56,56,56,56,56,37,37,56,37,37,56,56,56,56,56,56,56,56,37,56,56,37,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,63,63,63,63,63,63,37,63,63,37,37,63,63,63,60,55,+ 63,55,63,63,19,19,19,37,37,37,37,37,37,37,37,37,58,58,58,58,58,58,58,58,58,58,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,37,37,63,63,63,63,63,63,63,37,35,37,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,63,63,63,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,37,63,63,63,63,35,+ 37,19,19,19,19,35,37,63,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,19,19,19,37,35,35,35,19,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 35,35,35,35,35,35,35,35,35,35,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,37,63,63,63,63,63,63,63,63,+ 37,19,19,19,19,19,37,37,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,35,16,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,37,37,37,63,37,63,63,37,63,+ 63,63,63,63,63,63,37,63,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,37,63,63,37,63,63,63,63,63,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,19,63,63,63,63,19,19,37,37,37,37,37,37,37,+ 63,63,55,63,56,56,56,56,56,56,56,56,56,56,56,56,56,37,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,63,63,63,63,63,63,63,37,37,37,63,63,+ 63,63,60,19,19,42,42,42,42,42,42,42,42,42,42,42,58,58,58,58,58,58,58,58,58,58,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,48,48,48,48,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,19,19,19,19,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,21,21,21,12,12,12,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,12,37,37,37,21,12,21,12,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,21,12,12,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,21,10,10,10,10,10,10,10,21,12,10,10,10,21,12,21,12,+ 63,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,21,12,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,58,58,58,58,58,58,58,58,58,58,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,19,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,19,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,19,19,19,37,37,37,37,37,37,+ 37,37,37,37,19,37,37,37,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,19,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,+ 63,63,63,63,63,63,63,63,37,37,37,37,37,37,37,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,28,28,28,28,11,37,37,37,37,37,37,37,37,37,37,37,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,+ 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,37,37,37,37,37,37,37,37,+ 38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,+ 38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,+ 38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,+ 38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,38,+ 43,43,43,43,43,43,43,43,43,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,38,38,38,38,37,38,38,38,38,38,38,38,37,38,38,37,+ 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,65,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,65,65,65,37,37,65,37,37,37,37,37,37,37,37,37,37,37,37,37,37,65,65,65,65,37,37,37,37,37,37,37,37,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,+ 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,+ 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,19,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,+ 63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,+ 63,63,63,37,37,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,+ 38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,37,37,37,37,37,37,37,37,37,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,+ 63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,63,63,63,63,63,+ 63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,63,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,63,37,37,19,19,19,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 63,63,63,63,63,63,63,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,37,37,63,63,63,63,63,63,63,37,63,63,37,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,+ 39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,40,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,63,63,63,63,63,63,63,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,21,21,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,48,37,37,37,48,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 42,42,42,42,43,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,44,44,44,44,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,+ 42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,+ 42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,44,44,44,44,44,44,44,44,44,44,44,44,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,44,44,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,+ 44,42,42,42,42,42,42,42,42,42,42,42,42,42,42,43,44,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,44,44,44,44,44,44,44,44,44,44,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,38,37,37,38,38,38,38,38,38,38,38,38,38,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,+ 44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 43,43,43,44,44,44,44,44,44,44,44,44,44,44,44,44,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,44,44,44,44,+ 43,43,43,43,43,43,43,43,43,44,44,44,44,44,44,44,43,43,44,44,44,44,44,44,44,44,44,44,44,44,44,44,43,43,43,43,43,43,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,+ 44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,+ 44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,+ 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,42,42,42,42,42,42,42,42,42,42,42,42,43,43,43,43,43,43,43,43,43,42,43,43,43,43,43,43,43,43,43,+ 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,42,43,43,+ 43,43,43,43,43,46,43,43,43,43,43,43,43,43,43,43,43,43,43,43,42,42,42,42,42,42,42,42,37,37,42,42,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,38,38,43,43,43,43,43,38,43,43,43,+ 43,43,46,46,46,43,43,46,43,43,46,45,45,42,42,43,43,43,43,43,42,42,42,42,42,42,42,42,42,42,42,42,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,42,42,42,43,42,42,42,43,43,43,47,47,47,47,47,+ 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,42,+ 43,42,46,46,43,43,46,46,46,46,46,46,46,46,46,46,46,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,43,43,43,46,43,43,43,+ 43,46,46,46,43,46,46,46,43,43,43,43,43,43,43,46,43,46,43,43,43,43,43,43,43,43,43,43,43,43,43,43,38,43,38,43,38,43,43,43,43,43,46,43,43,43,43,38,43,38,38,43,43,43,43,43,43,43,43,43,43,43,43,43,+ 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,42,42,43,+ 38,38,38,38,38,38,38,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,38,38,38,38,38,38,38,38,38,38,38,38,38,38,43,43,43,43,43,43,43,43,43,43,43,43,43,38,38,38,38,38,38,38,38,38,38,38,38,37,37,+ 37,37,37,37,37,37,37,37,37,37,42,43,43,43,43,42,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,42,42,42,42,42,42,42,42,42,42,42,42,45,45,42,42,42,42,46,42,42,42,42,42,+ 42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,45,42,42,42,42,46,46,42,42,42,42,42,42,42,42,42,42,42,42,42,43,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,+ 42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,37,37,37,37,37,37,37,37,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,37,37,37,37,37,37,42,43,43,43,43,43,+ 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,+ 43,43,43,43,43,46,46,46,43,43,43,46,46,46,46,46,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,23,23,23,27,27,27,37,37,37,37,+ 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,46,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,46,46,46,43,43,43,43,43,43,43,43,43,+ 46,43,43,43,43,43,42,42,42,42,42,42,46,42,42,42,43,43,43,42,42,43,43,43,44,44,44,44,43,43,43,43,42,42,42,42,42,42,42,42,42,42,42,43,43,44,44,44,42,42,42,42,43,43,43,43,43,43,43,43,43,44,44,44,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,42,42,42,44,44,44,44,42,42,42,42,42,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,42,42,42,42,42,44,44,44,44,44,44,43,43,43,43,43,43,43,43,43,43,43,43,44,44,44,44,43,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,+ 37,37,37,37,37,37,37,37,37,37,37,37,46,43,43,46,43,43,43,43,43,43,43,43,46,46,46,46,46,46,46,46,43,43,43,43,43,43,46,43,43,43,43,43,43,43,43,43,46,46,46,46,46,46,46,46,46,46,43,42,46,46,46,43,+ 43,43,43,43,43,43,42,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,46,43,43,43,43,43,43,43,43,+ 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,46,46,43,46,46,43,46,43,43,43,43,+ 43,43,43,43,43,43,43,43,43,43,43,43,43,46,46,46,43,46,46,46,46,46,46,46,46,46,46,46,46,46,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+ 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,44,44,44,44,44,44,44,44,44,44,44,44,42,42,42,42,42,42,42,42,42,42,42,42,42,42,44,44,43,43,43,43,43,43,43,43,43,43,43,43,43,44,44,44,+ 43,43,43,43,43,43,43,43,43,43,44,44,44,44,44,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,+ 43,43,43,46,46,46,43,44,44,44,44,44,44,44,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,44,44,43,43,43,43,43,43,43,43,43,43,43,44,44,44,44,44,44,46,46,46,46,46,46,46,46,46,44,44,44,44,44,44,44,+ 44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,+ 44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,37,37,+ 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,+ 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,37,37,+ 37,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,+ 63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,+ 63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,+ 63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,+ 63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,+ 63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,+};++KBTS_INLINE kbts_u8 kbts__GetUnicodeLineBreakClass(kbts_u32 Codepoint)+{+ return (Codepoint < 1114110) ? kbts__UnicodeLineBreakClass_Data[((kbts_un)kbts__UnicodeLineBreakClass_PageIndices[Codepoint/128] * 128) | (Codepoint & 127)] : 0;+}++static kbts_u8 kbts__UnicodeGraphemeBreakClass_PageIndices[8703] = {+ 0,1,2,2,2,2,3,2,2,4,2,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,+ 26,27,28,29,2,2,30,2,2,2,2,2,2,2,31,32,33,34,35,2,36,37,38,39,40,41,2,42,2,2,2,2,+ 43,44,45,46,2,2,47,48,2,49,2,50,51,52,53,54,2,2,55,2,2,2,56,2,2,57,58,59,2,2,2,2,+ 60,61,2,2,2,62,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,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,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,+ 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,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,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,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,2,2,2,2,2,2,2,2,+ 2,2,2,2,2,2,2,2,2,2,2,2,63,64,2,2,65,66,67,68,69,70,2,71,72,73,74,75,76,77,78,79,+ 73,74,75,76,77,78,79,73,74,75,76,77,78,79,73,74,75,76,77,78,79,73,74,75,76,77,78,79,73,74,75,76,+ 77,78,79,73,74,75,76,77,78,79,73,74,75,76,77,78,79,73,74,75,76,77,78,79,73,74,75,76,77,78,79,73,+ 74,75,76,77,78,79,73,74,75,76,77,78,79,73,74,80,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,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,2,2,2,2,2,2,2,2,2,2,81,2,2,2,2,2,82,83,2,84,+ 2,2,2,85,2,86,87,2,2,2,2,2,2,2,2,2,2,2,2,2,88,89,2,2,2,2,90,2,2,91,92,93,+ 94,95,96,97,98,99,100,101,102,103,2,104,105,106,107,2,108,2,109,110,111,112,2,2,113,114,115,116,2,117,118,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,2,2,2,+ 2,2,2,2,2,2,2,2,119,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,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,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,120,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,121,122,2,2,2,123,2,2,2,124,125,+ 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,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,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,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,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,2,2,2,126,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,2,2,2,2,2,2,127,2,+ 2,2,128,129,130,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,131,132,2,2,2,2,2,2,2,2,2,2,+ 133,134,122,2,2,135,2,2,2,136,2,137,2,2,2,2,2,138,139,2,2,2,2,2,2,2,2,2,2,2,2,2,+ 140,140,141,142,143,140,140,144,140,140,145,140,146,140,147,148,149,150,151,140,140,140,2,2,140,140,140,140,140,140,140,152,+ 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+ 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+ 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+ 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+ 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+ 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+ 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+ 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+ 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+ 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+ 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+ 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+ 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,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,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,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,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,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,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,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,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,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,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,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,+ 153,154,155,156,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,+ 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+ 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+ 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+ 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,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,2,2,2,+};++static kbts_u8 kbts__UnicodeGraphemeBreakClass_Data[20096] = {+ 3,3,3,3,3,3,3,3,3,3,2,0,3,1,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,+ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,16,0,0,0,3,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,+ 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,0,14,+ 0,14,14,0,14,14,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 12,12,12,12,12,12,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,14,14,14,14,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,12,0,14,14,14,14,14,14,0,0,14,14,0,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,+ 14,14,14,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,14,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,0,14,14,14,14,14,14,14,14,14,0,14,14,14,0,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,12,0,0,0,0,0,14,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,12,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,+ 14,14,14,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,14,6,14,0,6,6,+ 6,14,14,14,14,14,14,14,14,6,6,6,6,15,6,6,0,14,14,14,14,14,14,14,13,13,13,13,13,13,13,13,0,0,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13,13,13,13,13,13,13,13,+ 0,14,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,0,13,13,13,13,13,13,13,0,13,0,0,0,13,13,13,13,0,0,14,0,14,6,+ 6,14,14,14,14,0,0,6,6,0,0,6,6,15,0,0,0,0,0,0,0,0,0,14,0,0,0,0,13,13,0,13,0,0,14,14,0,0,0,0,0,0,0,0,0,0,0,0,13,13,0,0,0,0,0,0,0,0,0,0,0,0,14,0,+ 0,14,14,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,6,6,+ 6,14,14,0,0,0,0,14,14,0,0,14,14,14,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,0,0,0,14,0,0,0,0,0,0,0,0,0,0,+ 0,14,14,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,0,13,13,13,13,13,13,13,0,13,13,0,13,13,13,13,13,0,0,14,0,6,6,+ 6,14,14,14,14,14,0,14,14,6,0,6,6,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13,14,14,14,14,14,14,+ 0,14,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,0,13,13,13,13,13,13,13,0,13,13,0,13,13,13,13,13,0,0,14,0,14,14,+ 6,14,14,14,14,0,0,6,6,0,0,6,6,15,0,0,0,0,0,0,0,14,14,14,0,0,0,0,13,13,0,13,0,0,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,13,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,6,+ 14,6,6,0,0,0,6,6,6,0,6,6,6,14,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 14,6,6,6,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,0,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,0,0,14,0,14,14,+ 14,6,6,6,6,0,14,14,14,0,14,14,14,15,0,0,0,0,0,0,0,14,14,0,13,13,13,0,0,0,0,0,0,0,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,14,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,6,14,+ 14,6,14,6,6,0,14,14,14,0,14,14,14,14,0,0,0,0,0,0,0,14,14,0,0,0,0,0,0,0,0,0,0,0,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,+ 14,14,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,14,14,0,14,6,+ 6,14,14,14,14,0,6,6,6,0,6,6,6,15,12,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,14,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,14,6,6,14,14,14,0,14,0,6,6,6,6,6,6,6,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,6,14,14,14,14,14,14,14,0,0,0,0,0,+ 0,0,0,0,0,0,0,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,6,14,14,14,14,14,14,14,14,14,0,0,0,+ 0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,14,0,14,0,0,0,0,6,6,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,14,14,14,14,14,14,14,6,+ 14,14,14,14,14,0,14,14,0,0,0,0,0,14,14,14,14,14,14,14,14,14,14,14,0,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,0,0,0,+ 0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,6,14,14,14,14,14,14,0,14,14,6,6,14,14,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,14,14,0,0,0,0,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,14,0,6,14,14,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 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,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,+ 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,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,6,14,14,14,14,14,14,14,6,6,+ 6,6,6,6,6,6,14,6,6,14,14,14,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,14,14,14,3,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,6,6,6,6,14,14,6,6,6,0,0,0,0,6,6,14,6,6,6,6,6,6,14,14,14,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,6,6,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,14,6,14,14,14,14,14,14,14,0,14,0,14,0,0,14,14,14,14,14,14,14,14,6,6,6,6,6,6,14,14,14,14,14,14,14,14,14,14,0,0,14,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,+ 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 14,14,14,14,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,14,14,14,6,6,+ 6,6,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,+ 14,14,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,14,14,14,14,6,6,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,6,14,14,6,6,6,14,6,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,6,6,6,6,6,6,14,14,14,14,14,14,14,14,6,6,14,14,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,0,14,14,14,14,14,14,14,14,14,14,14,14,14,6,14,14,14,14,14,14,14,0,0,0,0,14,0,0,0,0,0,0,14,0,0,6,14,14,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,+ 0,0,0,0,0,0,0,0,0,0,0,3,4,5,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,+ 0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,3,3,0,0,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,16,16,16,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,+ 16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,0,+ 16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,0,16,0,16,0,0,0,0,0,0,16,0,0,0,16,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,16,16,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,16,0,0,16,0,0,0,0,16,0,16,0,0,0,0,16,16,16,0,16,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,16,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,0,14,14,14,14,14,14,14,14,14,14,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,14,0,0,0,14,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,14,14,6,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,6,6,6,6,6,6,6,6,6,6,+ 6,6,6,6,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,14,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,14,14,14,14,14,14,14,14,14,14,14,6,14,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,+ 14,14,14,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,6,6,14,14,14,14,6,6,14,14,6,6,+ 14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,6,6,14,14,6,6,14,14,0,0,0,0,0,0,0,0,0,+ 0,0,0,14,0,0,0,0,0,0,0,0,14,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,14,14,14,0,0,14,14,0,0,0,0,0,14,14,+ 0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,14,14,6,6,0,0,0,0,0,6,14,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,14,6,6,14,6,6,0,6,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,+ 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,+ 10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,+ 10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,+ 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,+ 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,+ 10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,+ 9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,+ 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,+ 10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,+ 10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,+ 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,+ 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,+ 10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,+ 9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,+ 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,+ 10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,0,0,0,0,0,0,0,0,0,0,0,0,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,+ 8,8,8,8,8,8,8,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,3,0,3,3,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,0,0,0,0,0,+ 0,14,14,14,0,14,14,0,0,0,0,0,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,0,0,0,0,14,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,14,14,14,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 6,14,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,14,+ 14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,14,14,0,0,0,0,0,0,0,0,0,0,14,+ 14,14,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,6,14,14,14,14,6,6,14,14,0,0,12,0,0,+ 0,0,14,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,6,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,+ 14,14,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,6,14,14,14,14,14,14,14,14,14,6,+ 14,0,12,12,0,0,0,0,0,14,14,14,14,0,6,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,6,14,14,14,6,6,14,14,14,14,0,0,0,0,0,0,14,0,+ 0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,6,6,6,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 14,14,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,0,14,6,+ 14,6,6,6,6,0,0,6,6,0,0,6,6,14,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,6,6,0,0,14,14,14,14,14,14,14,0,0,0,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,6,6,14,14,14,14,14,+ 14,0,14,0,0,14,0,14,14,14,6,0,6,6,14,14,14,12,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,6,14,14,14,14,14,14,14,14,+ 6,6,14,14,14,6,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,6,6,14,14,14,14,14,14,6,14,6,6,14,6,14,+ 14,6,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,6,6,14,14,14,14,0,0,6,6,6,6,14,14,6,14,+ 14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,6,14,14,14,14,14,14,14,14,6,6,14,6,14,+ 14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,6,14,6,6,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,6,14,0,0,14,14,14,14,6,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,6,14,14,14,14,14,14,14,14,14,6,14,14,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,6,6,6,6,6,0,6,6,0,0,14,14,14,14,12,+ 6,12,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,6,14,14,14,14,0,0,14,14,6,6,6,6,14,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,14,14,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,6,12,14,14,14,14,0,+ 0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,6,6,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,12,12,12,12,12,12,14,14,14,14,14,14,14,14,14,14,14,14,14,6,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,14,14,14,14,14,14,14,0,14,14,14,14,14,14,6,14,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,0,6,14,14,14,14,14,14,14,6,14,14,6,14,14,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,0,0,0,14,0,14,14,0,14,+ 14,14,14,14,14,14,12,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,6,6,6,6,6,0,14,14,0,6,6,14,6,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,6,6,0,0,0,0,0,0,0,0,0,+ 14,14,12,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,14,14,14,14,14,0,0,0,6,6,+ 14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,+ 14,0,0,0,0,0,0,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,14,14,14,14,14,6,6,6,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,8,8,8,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,+ 6,6,6,6,6,6,6,6,0,0,0,0,0,0,0,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,0,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,0,0,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,+ 14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,0,0,0,14,14,14,14,14,14,3,3,3,3,3,3,3,3,14,14,14,14,14,+ 14,14,14,0,0,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,0,0,0,0,14,14,14,14,14,+ 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,0,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 14,14,14,14,14,14,14,0,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,0,0,14,14,14,14,14,14,14,0,14,14,0,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,16,16,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,+ 0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,16,16,16,16,16,16,16,16,16,0,16,16,16,16,+ 0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,14,14,14,14,14,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,+ 0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,+ 16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,+ 3,0,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,+ 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,+ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,+ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,+ 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,+ 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,+ 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,+ 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,+};++KBTS_INLINE kbts_u8 kbts__GetUnicodeGraphemeBreakClass(kbts_u32 Codepoint)+{+ return (Codepoint < 1114110) ? kbts__UnicodeGraphemeBreakClass_Data[((kbts_un)kbts__UnicodeGraphemeBreakClass_PageIndices[Codepoint/128] * 128) | (Codepoint & 127)] : 0;+}++static kbts_u8 kbts__UnicodeSyllabicInfo_PageIndices[8703] = {+ 0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,4,2,5,6,7,8,9,10,11,12,13,14,15,16,17,18,+ 19,20,2,2,2,2,2,2,2,2,2,2,2,2,21,22,23,24,25,26,27,28,29,30,31,32,2,33,2,2,2,2,+ 34,35,2,2,2,2,2,2,2,2,2,36,2,2,2,2,2,2,2,2,2,2,2,2,2,2,37,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,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,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,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,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,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,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,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,2,2,2,2,2,38,39,40,41,42,43,2,44,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,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,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,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,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,45,2,2,2,+ 2,2,2,2,2,2,2,2,2,2,46,47,2,2,2,2,2,2,2,2,48,49,2,2,2,2,50,51,2,52,53,54,+ 55,56,57,58,59,60,61,62,63,64,2,65,66,67,68,2,69,2,70,71,72,73,2,2,74,75,76,77,2,78,79,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,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,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,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,2,2,2,2,2,2,2,2,2,+ 2,2,80,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,81,82,2,2,2,83,2,2,2,84,85,+ 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,2,2,+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,86,86,86,87,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,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,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,2,2,2,2,88,89,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,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,2,2,2,2,2,2,2,2,2,2,+ 2,2,90,2,2,91,2,2,2,92,2,93,2,2,2,2,2,2,94,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,+};++static kbts_u16 kbts__UnicodeSyllabicInfo_Data[12160] = {+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,1034,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1034,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3592,3592,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1034,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,3,0,0,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,3,3,3,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 3592,3592,3592,3592,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1039,1025,1025,1025,1025,1025,1025,1025,1025,1025,2311,2311,2307,3601,2311,519,+ 2311,2311,2311,2311,2311,2311,2311,2311,2311,2311,2311,2311,2311,2308,519,2311,0,3593,3593,3592,3592,2311,2311,2311,1025,1025,1025,1025,1025,1025,1025,1025,+ 1026,1026,2311,2311,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,1026,1026,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,+ 1034,3592,3592,3592,0,1026,1026,1026,1026,1026,1026,1026,1026,0,0,1026,1026,0,0,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,0,1025,1025,1025,1025,1025,1025,1039,0,1025,0,0,0,1025,1025,1025,1025,0,0,2307,3601,3079,519,+ 3079,2311,2311,2311,2311,0,0,519,519,0,0,3079,3079,2308,1025,0,0,0,0,0,0,0,0,3079,0,0,0,0,1025,1025,0,1025,+ 1026,1026,2311,2311,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1025,1025,0,0,0,0,0,0,0,0,0,0,1034,0,3592,0,+ 0,3592,3592,3592,0,1026,1026,1026,1026,1026,1026,0,0,0,0,1026,1026,0,0,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,0,1025,1025,1025,1025,1025,1025,1039,0,1025,1025,0,1025,1025,0,1025,1025,0,0,3075,0,3079,519,+ 3085,3079,3079,0,0,0,0,3079,3079,0,0,3079,3079,3076,0,0,0,2055,0,0,0,0,0,0,0,1025,1025,1025,1025,0,1025,0,+ 0,0,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,3592,3592,1025,1025,0,1040,0,0,0,0,0,0,0,0,0,0,+ 0,3592,3592,3592,0,1026,1026,1026,1026,1026,1026,1026,1026,1026,0,1026,1026,1026,0,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,0,1025,1025,1025,1025,1025,1025,1039,0,1025,1025,0,1025,1025,1025,1025,1025,0,0,3075,3601,3079,519,+ 3079,3079,3079,3079,3079,2311,0,2311,2311,3079,0,3079,3079,3076,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1026,1026,3079,3079,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,0,0,0,1025,3593,2307,3593,2307,2307,2307,+ 0,1800,3592,3592,0,1026,1026,1026,1026,1026,1026,1026,1026,0,0,1026,1026,0,0,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,0,1025,1025,1025,1025,1025,1025,1039,0,1025,1025,0,1025,1025,1025,1025,1025,0,0,2307,3601,3079,1287,+ 3079,2311,2311,2311,2311,0,0,519,1287,0,0,3079,3079,2308,0,0,0,0,0,0,0,1283,1287,3079,0,0,0,0,1025,1025,0,1025,+ 1026,1026,2311,2311,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,1025,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,3592,0,0,1026,1026,1026,1026,1026,1026,0,0,0,1026,1026,1026,0,1026,1026,1026,1025,0,0,0,1025,1025,0,1025,0,1025,1025,+ 0,0,0,1025,1025,0,0,0,1025,1025,1025,0,0,0,1025,1025,1039,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,0,0,0,3079,3079,+ 2311,3079,3079,0,0,0,519,519,519,0,3079,3079,3079,2308,0,0,0,0,0,0,0,0,0,3079,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 3592,3592,3592,3592,3592,1026,1026,1026,1026,1026,1026,1026,1026,0,1026,1026,1026,0,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,0,1025,1025,1025,1025,1025,1025,1039,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,0,1795,3601,1799,1799,+ 1799,1799,1799,2311,2311,0,1799,1799,1799,0,1799,1799,1799,1796,0,0,0,0,0,0,0,1799,1799,0,1025,1025,1025,0,0,1025,0,0,+ 1026,1026,1799,1799,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1034,3592,3592,3592,0,1026,1026,1026,1026,1026,1026,1026,1026,0,1026,1026,1026,0,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,0,1025,1025,1025,1025,1025,1025,1039,1025,1025,1025,0,1025,1025,1025,1025,1025,0,0,1795,3601,1799,1799,+ 1799,1799,1799,2311,2311,0,1799,2311,2311,0,2311,2311,1799,1796,0,0,0,0,0,0,0,2311,2311,0,0,0,0,0,0,1025,1025,0,+ 1026,1026,1799,1799,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,1042,1042,3592,0,0,0,0,0,0,0,0,0,0,0,0,+ 3592,3592,3592,3592,1034,1026,1026,1026,1026,1026,1026,1026,1026,0,1026,1026,1026,0,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1039,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,3601,3079,3079,+ 3079,3079,3079,3079,3079,0,519,519,519,0,3079,3079,3079,4,14,0,0,0,0,0,1025,1025,1025,3079,0,0,0,0,0,0,0,1026,+ 1026,1026,3079,3079,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,0,0,0,0,1025,1025,1025,1025,1025,1025,+ 0,3592,3592,3592,0,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,0,0,0,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,1025,0,0,+ 1025,1025,1025,1025,1025,1025,1025,0,0,0,2308,0,0,0,0,2311,2311,2311,2311,2311,2311,0,2311,0,2311,519,2311,519,2311,2311,2311,2311,+ 0,0,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,2311,2311,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,0,+ 519,519,519,519,519,7,0,7,3,3,3,3,7,3592,7,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,1025,1025,0,1025,0,1025,1025,1025,1025,1025,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,0,1025,0,1025,1025,1025,1025,1025,1025,1025,1025,0,7,7,7,7,7,7,7,7,7,7,7,7,1040,1040,0,0,+ 519,519,519,519,519,0,0,0,3,3,3,3,0,3592,3592,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,1025,1025,1025,1025,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1025,1025,0,0,1025,1025,1025,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,3592,0,3592,0,3,0,0,0,0,0,0,+ 1025,1025,1025,1025,1025,1025,1025,1025,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,0,0,0,3,7,7,7,7,7,7,7,7,7,7,7,7,3592,1025,+ 7,7,3592,3592,7,3601,3,3,1025,1025,1025,1025,1025,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,0,1040,1040,1040,1040,1040,1040,1040,+ 1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,0,0,0,+ 0,0,0,0,0,0,3592,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1025,1025,1025,1025,1039,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1039,1025,1025,1025,1025,+ 1025,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,23,23,20,20,21,21,22,3593,20,20,20,3593,3,1034,4,27,33,31,32,30,1025,+ 1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,1025,0,1025,1025,1026,1026,1026,1026,23,23,21,21,1039,1025,1025,1025,33,33,+ 36,1025,23,34,34,1025,1025,23,23,34,34,34,34,34,1025,1025,1025,20,20,20,20,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,32,23,22,20,20,1034,1034,1034,1034,1034,1034,1034,1025,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,20,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,7,7,0,0,0,0,0,0,0,0,0,1025,+ 1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,7,0,0,0,0,0,0,0,0,0,0,0,+ 1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,0,0,0,0,0,0,0,0,0,0,0,0,+ 1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,1025,1025,1025,0,7,7,0,0,0,0,0,0,0,0,0,0,0,0,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1039,1025,1025,1025,1025,1025,+ 1025,1025,1025,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,0,0,23,20,20,20,20,21,21,21,20,23,+ 23,22,22,22,23,23,25,25,25,24,24,25,24,25,25,25,25,25,4,25,0,0,0,0,0,1034,0,0,3601,25,0,0,+ 1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1025,0,0,0,0,0,0,1025,0,0,1025,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,0,0,0,0,0,0,+ 1034,1034,1034,1034,1034,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1034,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,+ 7,7,7,7,7,7,7,7,7,1040,1040,1040,0,0,0,0,1040,1040,3592,1040,1040,1040,1040,1040,1040,1040,3592,3592,0,0,0,0,+ 0,0,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,0,0,0,7,7,7,7,7,519,519,519,7,7,519,7,7,7,7,7,+ 7,1025,1025,1025,1025,1025,1025,1025,3,3,0,0,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,7,7,7,0,0,0,0,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1026,1026,1026,1026,1026,1026,1025,1025,1040,1040,1040,1040,1040,1025,1040,1040,1040,1040,0,+ 4,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,3592,3,3,3,3,3,7,3,3,0,0,3,+ 1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 3592,3592,3592,1040,3592,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,3,7,7,7,7,7,7,7,7,7,7,7,+ 7,7,7,7,4,1025,1025,1025,1025,1025,1025,1025,1025,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 3592,1040,3592,1026,1026,1026,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1040,1040,1040,7,7,7,7,7,7,7,4,1040,1040,1025,1025,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,3601,1025,1025,1025,1040,1040,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1026,1026,3,7,7,7,7,7,7,7,7,7,1040,1040,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1040,1040,7,7,7,7,7,7,7,1040,1040,1040,1040,1040,1040,1040,3592,3592,0,3,0,0,0,0,0,0,0,0,+ 1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,1025,1025,1025,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3593,3593,3593,0,3593,3593,3593,3593,3593,3593,3593,3593,3593,3593,3593,3593,+ 3593,3593,3593,3593,3593,3593,3593,3593,3593,3601,3601,3601,3601,3593,3601,3601,3601,3601,1025,1025,3593,1025,1025,3593,3593,3593,1034,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3592,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,5,6,0,0,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,0,0,0,0,+ 0,0,1034,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3592,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,3592,3592,3592,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3593,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,1035,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1034,1034,1034,1034,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,0,0,0,0,0,0,0,1025,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,+ 1026,1026,7,1026,1026,1026,4,1025,1025,1025,1025,3592,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,7,7,7,7,7,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1026,1026,+ 1026,1026,1025,1025,1025,1025,1026,1040,1040,1025,1025,1025,1025,1025,1025,1025,1025,1040,1025,3592,0,0,0,0,0,0,0,0,0,0,0,0,+ 3592,3592,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1040,7,7,7,7,7,7,7,7,7,7,7,+ 7,7,7,7,4,3592,0,0,0,0,0,0,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,+ 3593,3593,3593,3593,3593,3593,3593,3593,3593,3593,3593,3593,3593,3593,3593,3593,3593,3593,3601,3601,3601,3601,3601,3601,0,0,0,0,0,0,1026,2311,+ 1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1026,1026,1026,1026,1026,1026,1026,1026,1026,3,3,3,0,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,7,7,7,7,7,7,7,7,1040,1040,1040,1040,7,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 3592,3592,1040,3592,1026,1026,1026,1026,1026,1025,1025,1025,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,3,7,7,7,7,7,7,7,7,7,1040,1040,1040,+ 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,+ 1025,1025,1025,1025,1025,20,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1025,1025,1025,1025,1025,0,+ 1026,1026,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,3592,7,7,7,7,7,7,7,7,7,1040,1040,1040,1040,0,0,0,0,0,0,0,0,0,+ 1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,1025,1025,1025,1034,1034,1034,0,0,0,1025,34,3,3,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,1026,7,7,7,519,519,7,7,519,1026,519,519,1026,7,3,+ 0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,7,7,7,0,0,0,0,0,3592,4,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1026,1026,1025,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1040,1040,1040,1040,1040,+ 1040,1040,1040,7,7,7,7,7,7,7,7,0,3,7,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,+ 35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,1025,1025,1025,1025,1025,1025,1025,0,1025,1025,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,1025,1025,1025,1025,1025,1025,1025,0,1025,1025,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1025,1287,7,7,0,7,1287,0,0,0,0,0,7,3592,3592,3592,1025,1025,1025,1025,0,1025,1025,1025,0,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,0,3,3,3,0,0,0,0,4,+ 1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1025,1025,1025,1025,1025,1025,1025,1025,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,3,3,3,3592,0,0,0,0,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,0,0,0,7,7,7,7,7,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,7,7,0,0,0,1025,1025,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,3,3,3,3,3,3,3,3,3,3,3,1034,1034,1034,1034,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 3592,3592,3592,1042,1042,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,7,7,7,7,7,7,+ 7,7,7,7,7,7,4,0,0,0,0,0,0,0,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,+ 1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,7,1026,1026,7,7,1025,0,0,0,0,0,0,0,0,0,1034,+ 3592,3592,3592,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,7,7,7,7,7,7,7,4,3,0,0,0,0,0,+ 0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 3592,3592,3592,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,7,7,7,7,7,7,7,7,7,7,7,7,4,3592,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,+ 0,0,0,0,1025,7,7,1025,0,0,0,0,0,0,0,0,1026,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,3,0,0,0,0,0,0,0,0,0,0,0,0,+ 3592,3592,3592,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,7,7,7,7,7,7,7,7,7,7,7,+ 4,3601,0,0,0,0,0,0,0,3592,3,7,7,0,7,3592,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1025,0,0,0,0,0,+ 0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,0,0,0,0,0,+ 1026,1026,1026,1026,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,7,7,7,7,7,7,3592,4,3,3592,0,0,0,0,0,0,3593,1025,+ 1026,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1026,1026,1026,1026,1025,1025,1025,0,1025,0,1025,1025,1025,1025,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,0,0,0,0,0,0,0,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,3592,+ 7,7,7,7,7,7,7,7,7,3,7,0,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,+ 3592,3592,3592,3592,0,1026,1026,1026,1026,1026,1026,1026,1026,0,0,1026,1026,0,0,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,0,1025,1025,1025,1025,1025,1025,1025,0,1025,1025,0,1025,1025,1025,1025,1025,0,3,3,3601,7,7,+ 7,7,7,7,7,0,0,7,7,0,0,7,7,4,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,3592,3592,+ 1026,1026,7,7,0,0,3593,3593,3593,3593,3593,3593,3593,0,0,0,3593,3593,3593,3593,3593,0,0,0,0,0,0,0,0,0,0,0,+ 1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,0,1026,0,0,1026,0,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,3601,7,7,7,7,7,7,7,7,+ 7,0,7,0,0,7,0,7,7,7,3592,0,3592,3592,3592,3,4,14,3592,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,3593,3593,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,7,7,7,7,7,7,7,7,7,+ 7,7,4,3592,3592,3592,3,3601,0,0,0,0,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,3592,3592,+ 1042,1042,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,3592,+ 3592,3592,4,3,3601,0,0,0,0,0,0,0,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,7,7,7,7,7,0,0,7,7,7,7,3592,3592,3592,4,+ 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1026,1026,1026,1026,7,7,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,7,7,7,7,7,7,7,7,7,7,7,3592,3592,4,+ 7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,3592,3592,7,7,7,7,7,7,7,7,7,4,3,1025,0,0,0,0,0,0,0,+ 1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,+ 1034,1034,1034,1034,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,0,1040,1040,1040,+ 7,7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,+ 1025,1025,1025,1025,1025,1025,1025,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,7,7,7,7,7,7,7,7,7,3592,3592,4,3,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1026,1026,1026,1026,1026,1026,1026,0,0,1026,0,0,1025,1025,1025,1025,1025,1025,1025,1025,0,1025,1025,0,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,7,7,7,7,0,7,7,0,0,3592,3592,7,4,0,+ 1040,14,1040,3,0,0,0,0,0,0,0,0,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1026,1026,1026,1026,1026,1026,1026,1026,0,0,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,7,7,7,7,7,0,0,7,7,7,7,3592,3592,+ 4,3601,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1026,7,7,7,7,7,7,7,7,7,7,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,3592,7,3592,3592,3592,3592,3592,1042,1040,1040,1040,1040,1034,+ 0,0,0,0,0,1034,0,4,0,0,0,0,0,0,0,0,1026,7,7,7,7,7,7,7,7,7,7,7,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,0,0,0,0,0,0,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,3592,3592,3592,4,0,0,0,3601,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1026,1026,1026,1026,1026,1026,1026,1026,1026,0,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,7,7,7,7,7,7,0,7,7,7,7,3592,3592,3592,4,+ 3601,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,+ 1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,0,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,+ 1040,1040,1040,1040,1040,1040,1040,1040,0,1040,1040,1040,1040,1040,1040,1040,7,7,7,7,7,3592,3592,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1026,1026,1026,1026,1026,1026,1026,0,1026,1026,0,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,7,7,7,7,0,0,0,7,0,7,7,0,7,+ 3592,3592,3,7,7,4,14,1040,0,0,0,0,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,+ 1026,1026,1026,1026,1026,1026,0,1026,1026,0,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,7,7,7,0,7,7,0,7,7,3592,3592,4,0,0,0,0,0,0,0,0,+ 1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1034,7,7,7,7,0,0,0,0,0,0,0,0,0,+ 3592,3592,14,3592,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,7,7,7,7,7,0,0,0,7,7,+ 7,7,4,0,0,0,0,0,0,0,0,0,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,3,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,+ 7,7,7,7,7,7,7,7,7,7,1040,1040,1040,3592,1040,7,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 3592,3592,3592,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,7,7,7,7,7,7,7,7,7,7,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,0,0,0,3,0,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,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,+ 7,7,7,7,7,7,7,7,0,0,0,0,0,0,0,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,1025,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,0,0,0,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,0,0,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,0,0,0,0,0,0,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,0,0,1283,1283,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,0,0,3,3,3,3,3,3,3,1025,1025,1025,1025,1025,1025,1025,0,0,+ 1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,1025,1025,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,3,3,3,3,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,7,7,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,1025,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,3,3,3,3,3,3,3,1025,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+};++KBTS_INLINE kbts_u16 kbts__GetUnicodeSyllabicInfo(kbts_u32 Codepoint)+{+ return (Codepoint < 1114110) ? kbts__UnicodeSyllabicInfo_Data[((kbts_un)kbts__UnicodeSyllabicInfo_PageIndices[Codepoint/128] * 128) | (Codepoint & 127)] : 0;+}++static kbts_u8 kbts__UnicodeFlags_PageIndices[8703] = {+ 0,1,2,3,2,4,5,6,2,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,+ 30,31,32,33,34,35,36,37,38,33,33,33,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,2,2,2,55,+ 56,57,58,59,60,61,62,33,63,33,33,33,33,33,64,65,33,33,33,66,67,68,69,70,71,72,73,74,75,76,33,77,+ 78,79,80,81,82,33,33,33,83,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,84,83,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,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,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,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,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,2,2,2,2,2,2,2,2,2,2,2,2,85,+ 33,33,33,33,33,33,33,33,33,86,33,33,87,88,89,90,91,92,93,94,95,96,97,98,83,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,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,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,99,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,+ 83,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,2,+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,85,33,33,100,101,102,103,33,33,104,105,106,107,108,109,+ 110,111,112,113,2,114,115,116,117,118,119,120,33,33,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,+ 139,140,141,142,143,144,145,146,147,148,2,149,150,151,152,2,153,154,155,156,157,158,2,159,160,161,162,163,2,164,165,166,+ 33,33,33,33,33,33,33,37,167,33,168,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,169,+ 33,33,33,33,33,33,33,33,170,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,+ 33,33,33,33,33,33,33,111,33,33,33,33,171,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,+ 2,2,172,2,2,2,2,2,2,2,2,2,2,2,2,2,33,33,33,33,173,174,175,176,2,2,177,2,2,178,179,180,+ 83,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,2,+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,181,33,33,33,33,33,33,33,33,33,182,183,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,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,2,2,2,2,2,2,2,2,184,+ 33,33,185,33,33,186,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,187,188,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,33,189,33,33,33,190,191,168,+ 33,192,193,194,195,196,197,2,2,2,2,2,2,198,199,200,33,33,33,33,201,202,2,2,2,2,2,2,2,2,203,2,+ 204,205,206,2,2,207,2,2,2,208,2,209,2,2,2,210,33,211,212,2,2,2,2,2,213,214,215,2,216,217,2,2,+ 218,219,33,220,221,2,33,33,33,33,33,33,33,222,223,224,225,226,33,33,227,228,33,229,2,2,2,2,2,2,2,2,+ 83,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,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,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,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,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,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,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,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,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,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,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,2,2,230,83,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,2,231,2,232,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,233,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,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,234,2,2,2,2,235,2,2,2,+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,33,33,33,33,236,2,2,2,2,2,2,2,2,2,2,2,+ 83,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,2,+ 2,2,2,2,2,2,237,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,2,2,238,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,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,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,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,+ 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+ 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+ 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+ 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+ 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+ 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+ 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+ 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+ 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+ 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+ 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+ 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,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,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,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,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,2,2,2,2,2,2,2,2,2,2,+ 239,239,240,241,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,+ 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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+ 83,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,242,+ 83,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,+};++static kbts_u8 kbts__UnicodeFlags_Data[31104] = {+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,4,8,0,16,0,0,0,0,48,48,48,48,48,48,48,48,48,48,0,0,28,16,28,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,8,16,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,16,8,16,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,0,16,16,16,12,16,2,16,16,16,16,16,16,16,0,0,0,16,16,16,12,16,16,16,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,+ 16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,+ 80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,82,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,0,0,0,0,16,16,0,0,0,0,16,0,0,0,0,0,+ 0,0,0,0,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,+ 0,0,16,80,80,80,80,80,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,0,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,0,80,+ 0,80,80,0,80,80,0,80,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,16,16,16,0,0,16,0,0,16,16,80,80,80,80,80,80,80,80,80,80,80,0,2,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,80,80,80,81,81,80,80,81,80,80,80,80,80,80,80,48,48,48,48,48,48,48,48,48,48,0,0,0,0,16,16,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,80,80,80,80,80,80,81,0,16,80,80,80,80,81,80,16,16,81,81,16,80,80,80,80,16,16,48,48,48,48,48,48,48,48,48,48,16,16,16,16,16,16,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,+ 80,80,80,80,80,80,80,80,80,80,80,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,80,80,80,80,80,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 48,48,48,48,48,48,48,48,48,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,80,80,80,16,16,16,0,0,0,16,0,0,80,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,16,80,80,80,80,80,80,80,80,80,16,80,80,80,16,80,80,80,80,80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,80,80,80,80,80,80,80,80,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,81,81,80,81,81,81,80,80,80,81,80,80,80,80,80,80,80,80,80,80,80,80,80,80,0,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,81,80,80,80,80,80,80,80,80,80,80,80,80,+ 80,80,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,16,80,16,16,16,+ 16,80,80,80,80,80,80,80,80,16,16,16,16,80,16,16,16,80,80,80,80,80,80,80,16,16,16,16,16,16,16,16,16,16,80,80,0,0,48,48,48,48,48,48,48,48,48,48,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,80,16,16,0,16,16,16,16,16,16,16,16,0,0,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,0,16,0,0,0,16,16,16,16,0,0,80,16,16,16,+ 16,80,80,80,80,0,0,16,16,0,0,16,16,80,16,0,0,0,0,0,0,0,0,16,0,0,0,0,16,16,0,16,16,16,80,80,0,0,48,48,48,48,48,48,48,48,48,48,16,16,16,16,16,16,16,16,16,16,16,16,16,0,80,0,+ 0,80,80,16,0,16,16,16,16,16,16,0,0,0,0,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,0,16,16,0,16,16,0,16,16,0,0,80,0,16,16,+ 16,80,80,0,0,0,0,80,80,0,0,80,80,80,0,0,0,80,0,0,0,0,0,0,0,16,16,16,16,0,16,0,0,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,80,80,16,16,16,80,0,0,0,0,0,0,0,0,0,0,+ 0,80,80,16,0,16,16,16,16,16,16,16,16,16,0,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,0,16,16,0,16,16,16,16,16,0,0,80,16,16,16,+ 16,80,80,80,80,80,0,80,80,16,0,16,16,80,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,80,80,0,0,48,48,48,48,48,48,48,48,48,48,0,16,0,0,0,0,0,0,0,16,80,80,80,80,80,80,+ 0,80,16,16,0,16,16,16,16,16,16,16,16,0,0,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,0,16,16,0,16,16,16,16,16,0,0,80,16,16,80,+ 16,80,80,80,80,0,0,16,16,0,0,16,16,80,0,0,0,0,0,0,0,80,80,16,0,0,0,0,16,16,0,16,16,16,80,80,0,0,48,48,48,48,48,48,48,48,48,48,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,+ 0,0,80,16,0,16,16,16,16,16,16,0,0,0,16,16,16,0,16,16,16,16,0,0,0,16,16,0,16,0,16,16,0,0,0,16,16,0,0,0,16,16,16,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,16,16,+ 80,16,16,0,0,0,16,16,16,0,16,16,16,80,0,0,16,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,+ 80,16,16,16,80,16,16,16,16,16,16,16,16,0,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,80,16,80,80,+ 80,16,16,16,16,0,80,80,80,0,80,80,80,80,0,0,0,0,0,0,0,80,80,0,16,16,16,0,0,16,0,0,16,16,80,80,0,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,+ 16,80,16,16,0,16,16,16,16,16,16,16,16,0,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,0,0,80,16,16,80,+ 16,16,16,16,16,0,80,16,16,0,16,16,80,80,0,0,0,0,0,0,0,16,16,0,0,0,0,0,0,16,16,0,16,16,80,80,0,0,48,48,48,48,48,48,48,48,48,48,0,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,+ 80,80,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,16,16,16,+ 16,80,80,80,80,0,16,16,16,0,16,16,16,80,16,16,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,0,0,48,48,48,48,48,48,48,48,48,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 0,80,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,0,16,0,0,+ 16,16,16,16,16,16,16,0,0,0,80,0,0,0,0,16,16,16,80,80,80,0,80,0,16,16,16,16,16,16,16,16,0,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,0,0,16,16,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,16,16,80,80,80,80,80,80,80,0,0,0,0,16,+ 16,16,16,16,16,16,16,80,80,80,80,80,80,80,80,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,16,16,0,16,0,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,0,16,16,16,16,16,16,16,16,16,16,80,16,16,80,80,80,80,80,80,80,80,80,16,0,0,+ 16,16,16,16,16,0,16,0,80,80,80,80,80,80,80,0,48,48,48,48,48,48,48,48,48,48,0,0,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,16,16,16,80,80,16,16,16,16,16,16,48,48,48,48,48,48,48,48,48,48,16,16,16,16,16,16,16,16,16,16,16,80,16,80,16,80,4,8,4,8,16,16,+ 16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,80,80,80,80,80,80,80,80,80,80,80,80,80,80,16,+ 80,80,80,80,80,0,80,80,16,16,16,16,16,80,80,80,80,80,80,80,80,80,80,80,0,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,0,16,16,+ 16,16,16,16,16,16,80,16,16,16,16,16,16,0,16,16,0,0,0,0,0,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,16,80,80,80,80,80,80,16,80,80,16,16,80,80,16,+ 48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,16,16,16,16,16,16,16,16,80,80,16,16,16,16,80,80,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,80,16,16,80,80,16,16,16,16,16,16,80,16,16,48,48,48,48,48,48,48,48,48,48,16,16,16,80,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,18,18,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,0,16,16,16,16,0,0,16,16,16,16,16,16,16,0,16,0,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,0,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,0,0,16,16,16,16,16,16,16,0,+ 16,0,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,80,80,80,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,4,8,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,16,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,16,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,0,80,80,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,82,82,16,80,80,80,80,80,80,80,16,16,+ 16,16,16,16,16,16,80,16,16,80,80,80,80,80,80,80,80,80,80,80,0,0,0,16,0,0,0,16,16,80,0,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,82,82,82,2,82,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,+ 16,16,16,16,16,80,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,16,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,80,80,80,16,16,16,16,80,80,16,16,16,0,0,0,0,16,16,80,16,16,16,16,16,16,80,80,80,0,0,0,0,+ 16,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,16,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,16,16,80,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,16,80,80,80,80,80,80,80,0,80,16,80,16,16,80,80,80,80,80,80,80,80,16,16,16,16,16,16,80,80,80,80,80,80,80,80,80,80,0,0,80,+ 48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,80,80,80,80,80,80,80,80,80,80,80,80,80,80,16,80,+ 80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 80,80,80,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,16,80,80,80,80,80,16,80,16,16,16,+ 16,16,80,16,16,16,16,16,16,16,16,16,16,0,0,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,80,80,80,16,16,16,16,16,16,16,16,16,0,0,0,+ 80,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,16,16,80,80,16,80,80,80,16,16,48,48,48,48,48,48,48,48,48,48,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,16,80,80,16,16,16,80,16,80,80,80,16,16,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,80,80,16,16,80,80,0,0,0,0,0,0,0,0,+ 48,48,48,48,48,48,48,48,48,48,0,0,0,16,16,16,48,48,48,48,48,48,48,48,48,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,80,80,80,0,80,80,80,80,80,80,80,80,80,80,80,80,80,16,80,80,80,80,80,80,80,16,16,16,16,80,16,16,16,16,16,16,80,16,16,16,80,80,16,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,16,+ 16,16,0,0,0,0,0,0,0,0,0,0,0,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,0,+ 0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,12,12,0,0,0,0,0,+ 0,0,0,0,16,4,8,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,16,16,0,0,16,16,16,16,16,16,16,16,16,4,8,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,4,8,0,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,80,80,80,80,80,80,80,80,80,80,80,80,80,16,16,16,16,80,16,16,16,80,80,80,80,80,80,80,80,80,80,80,80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,0,16,16,16,16,0,16,16,0,0,0,0,0,0,0,0,0,0,16,0,16,16,16,0,0,0,0,0,16,16,16,16,16,16,0,16,0,16,0,16,0,0,0,0,16,0,0,0,0,0,0,16,16,16,16,0,16,16,0,0,0,0,+ 16,16,16,16,16,0,0,0,0,0,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,0,0,16,16,16,16,16,16,16,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,28,28,28,28,28,28,16,16,16,16,16,16,16,28,16,16,16,16,16,16,16,16,16,28,28,28,28,16,28,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,28,28,16,16,+ 16,16,16,28,16,28,16,16,16,16,16,16,28,16,16,16,16,16,28,28,28,28,16,16,16,16,16,16,16,16,16,16,16,16,16,16,28,28,28,28,28,28,28,28,16,16,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,+ 28,28,28,28,28,28,28,28,28,28,28,28,16,16,16,28,28,28,28,16,16,16,16,16,28,16,16,16,16,16,16,16,16,16,28,28,16,16,28,16,28,28,16,28,16,16,16,16,28,28,28,28,28,28,28,28,28,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,28,28,28,28,28,16,16,28,28,16,16,16,16,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,16,16,28,28,28,28,28,16,28,28,16,16,28,28,28,28,28,16,+ 16,16,16,16,16,16,16,16,4,8,4,8,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,4,8,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,4,8,4,8,4,8,4,8,4,8,4,8,4,8,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,28,28,4,8,16,28,28,16,28,16,28,16,16,16,16,16,16,16,28,28,16,16,16,16,16,28,28,28,16,16,16,28,28,28,28,4,8,4,8,4,8,4,8,4,8,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,4,8,4,8,4,8,4,8,4,8,4,8,4,8,4,8,4,8,4,8,4,8,16,16,28,16,16,16,16,28,16,16,28,28,28,16,16,28,28,28,28,28,28,28,28,16,16,16,16,16,16,16,16,28,16,16,16,16,16,16,16,+ 28,28,16,16,28,28,16,16,16,16,16,16,16,16,16,28,28,28,28,16,28,28,16,16,4,8,4,8,16,16,16,16,16,16,16,16,16,16,16,16,28,28,16,16,16,16,16,16,16,16,16,16,16,28,16,16,28,28,16,16,4,8,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,28,28,28,28,16,16,16,16,16,28,28,16,16,16,16,16,16,28,28,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,28,28,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,28,28,28,28,28,28,28,+ 28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,16,16,16,28,28,28,28,28,28,28,28,16,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,+ 28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,16,16,16,16,16,16,16,28,16,16,16,16,28,28,28,16,16,16,16,16,16,28,28,28,16,16,16,16,16,16,16,16,28,28,28,28,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,28,16,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,0,0,0,0,80,80,80,0,0,0,0,0,0,0,0,0,0,0,16,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,80,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,0,+ 16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,0,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,+ 0,0,12,12,12,12,0,0,0,12,12,0,12,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,12,0,0,12,12,4,8,4,8,4,8,4,8,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,0,0,0,4,8,4,8,4,8,4,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 0,0,0,0,16,16,16,16,4,8,4,8,4,8,4,8,4,8,16,16,4,8,4,8,4,8,4,8,0,0,0,0,16,16,16,16,16,16,16,16,16,16,80,80,80,80,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,+ 0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,80,80,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,+ 0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,18,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,48,48,48,48,48,48,48,48,48,48,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,80,16,16,16,0,80,80,80,80,80,80,80,80,80,80,0,16,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,80,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,16,16,16,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,0,0,16,16,16,0,16,16,16,16,16,+ 16,16,80,16,16,16,80,16,16,16,16,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,16,16,16,16,16,80,0,0,0,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,80,80,0,0,0,0,0,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,16,16,16,16,16,16,0,0,0,16,0,16,16,80,+ 48,48,48,48,48,48,48,48,48,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,80,80,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,80,80,80,80,80,80,80,80,80,80,80,16,16,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,+ 80,80,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,16,16,80,80,80,80,16,16,80,80,16,16,+ 16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,16,16,16,16,16,80,16,16,16,16,16,16,16,16,16,16,48,48,48,48,48,48,48,48,48,48,16,16,16,16,16,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,16,16,80,80,16,16,80,80,0,0,0,0,0,0,0,0,0,+ 16,16,16,80,16,16,16,16,16,16,16,16,80,16,0,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,16,80,80,80,16,16,80,80,16,16,16,16,16,80,80,+ 16,80,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,80,80,16,16,0,0,16,16,16,16,80,0,0,0,0,0,0,0,0,0,+ 0,16,16,16,16,16,16,0,0,16,16,16,16,16,16,0,0,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,0,0,0,0,0,0,0,0,0,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,16,16,80,16,16,0,16,80,0,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,0,16,0,+ 16,16,0,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,8,4,8,4,8,0,0,0,16,0,28,28,16,0,0,16,0,0,0,0,0,0,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,2,+ 0,0,0,0,16,0,0,0,4,8,0,16,0,0,0,0,48,48,48,48,48,48,48,48,48,48,0,0,28,16,28,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,8,16,0,+ 16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,16,8,16,4,8,0,4,8,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,18,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,+ 0,0,16,16,16,16,16,16,0,0,16,16,16,16,16,16,0,0,16,16,16,16,16,16,0,0,16,16,16,0,0,0,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,0,2,2,2,2,2,2,2,2,2,0,0,0,16,16,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,0,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,+ 0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,0,0,0,0,16,16,16,16,16,16,16,16,0,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,0,0,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,0,0,0,16,0,0,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,0,0,0,0,0,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,80,80,80,0,80,80,0,0,0,0,0,80,80,80,80,16,16,16,16,0,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,80,80,80,0,0,0,0,80,+ 16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,0,0,0,0,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,0,0,0,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,+ 48,48,48,48,48,48,48,48,48,48,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,80,80,80,80,80,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,80,80,0,0,0,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,80,80,80,80,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,80,80,80,80,80,80,80,80,80,80,80,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,80,80,80,80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,+ 16,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,80,80,+ 80,80,80,80,80,80,80,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,48,48,48,48,48,48,48,48,48,48,80,16,16,80,80,16,0,0,0,0,0,0,0,0,0,80,+ 80,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,16,16,80,80,0,0,0,0,0,+ 0,0,80,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,+ 80,80,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,16,80,80,80,80,80,80,80,80,0,48,48,48,48,48,48,48,48,48,48,+ 0,0,0,0,16,16,16,16,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,0,0,16,0,0,0,0,0,0,0,0,0,+ 80,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,80,80,80,16,+ 16,16,16,16,16,0,0,0,0,80,80,80,80,0,16,80,48,48,48,48,48,48,48,48,48,48,16,0,16,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,16,16,80,16,80,80,0,0,0,0,0,0,80,16,+ 16,80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,0,16,0,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,16,16,16,80,80,80,80,80,80,80,80,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,+ 80,80,16,16,0,16,16,16,16,16,16,16,16,0,0,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,0,16,16,0,16,16,16,16,16,0,80,80,16,16,16,+ 80,16,16,16,16,0,0,16,16,0,0,16,16,16,0,0,16,0,0,0,0,0,0,16,0,0,0,0,0,16,16,16,16,16,16,16,0,0,80,80,80,80,80,80,80,0,0,0,80,80,80,80,80,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,0,16,0,0,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,80,80,80,80,80,+ 80,0,16,0,0,16,0,16,16,16,16,0,16,16,80,16,80,16,80,16,0,0,0,0,0,0,0,0,0,0,0,0,0,80,80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,80,80,+ 16,16,80,80,80,16,80,16,16,16,16,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,80,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,16,80,16,16,16,16,80,+ 80,16,80,80,16,16,0,16,0,0,0,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,0,0,16,16,16,16,80,80,16,80,+ 80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,80,80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,80,80,16,16,80,16,80,+ 80,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,16,80,16,16,80,80,80,80,80,80,16,80,16,0,0,0,0,0,0,0,+ 48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,80,16,80,16,16,80,80,80,80,16,80,80,80,80,80,0,0,0,0,48,48,48,48,48,48,48,48,48,48,16,16,0,0,0,16,+ 16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,80,80,80,16,80,80,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,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,48,48,48,48,48,48,48,48,48,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,16,+ 16,16,16,16,16,16,16,0,0,16,0,0,16,16,16,16,16,16,16,16,0,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,0,0,80,80,16,80,16,+ 16,16,16,80,0,0,0,0,0,0,0,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,0,0,80,80,16,16,16,16,80,16,0,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,80,80,80,80,80,80,80,80,80,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,16,16,80,80,80,80,0,+ 0,0,0,0,0,0,0,80,0,0,0,0,0,0,0,0,16,80,80,80,80,80,80,16,16,80,80,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,80,80,80,80,80,80,80,16,80,80,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,80,0,80,80,80,80,80,80,16,80,+ 16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,0,16,80,80,80,80,80,80,80,16,80,80,16,80,80,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,0,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,0,0,0,80,0,80,80,0,80,+ 80,80,80,80,80,80,16,80,0,0,0,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,16,16,16,16,16,16,0,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,80,80,0,16,16,80,16,80,16,0,0,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,16,16,0,0,0,0,0,0,0,0,0,+ 80,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,0,0,0,16,16,+ 80,16,80,0,0,0,0,0,0,0,0,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 80,16,16,16,16,16,16,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,80,80,80,80,80,80,16,16,16,80,80,80,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,+ 48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,80,80,80,80,80,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,80,0,0,0,0,0,16,16,16,16,+ 16,16,16,16,0,16,0,0,0,0,0,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,0,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,80,80,80,80,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,0,16,80,0,0,0,0,0,0,0,0,0,0,0,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,+ 16,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,0,16,16,16,16,16,16,16,0,16,16,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,+ 16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,0,0,16,80,80,0,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,0,0,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,+ 80,80,80,80,80,80,80,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,16,16,16,16,16,16,16,16,16,2,2,2,2,2,2,2,2,80,80,80,80,80,+ 80,80,80,16,16,80,80,80,80,80,80,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,80,80,80,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,16,0,0,0,0,0,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,+ 80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,16,16,16,16,80,80,80,80,80,+ 80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,16,16,16,16,16,16,16,16,80,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,80,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,80,80,80,80,80,0,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 80,80,80,80,80,80,80,0,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,0,0,80,80,80,80,80,80,80,0,80,80,0,80,80,80,80,80,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,80,80,80,80,80,80,80,16,16,16,16,16,16,16,0,0,+ 48,48,48,48,48,48,48,48,48,48,0,0,0,0,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,16,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,16,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,0,16,16,16,16,0,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,80,80,80,80,80,80,80,16,0,0,0,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,0,16,0,0,16,0,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,0,16,0,16,0,0,0,0,+ 0,0,16,0,0,0,0,16,0,16,0,16,0,16,16,16,0,16,16,0,16,0,0,16,0,16,0,16,0,16,0,16,0,16,16,0,16,0,0,16,16,16,16,0,16,16,16,16,16,16,16,0,16,16,16,16,0,16,16,16,16,0,16,0,+ 16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,16,16,16,0,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,+ 16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,+ 16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 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,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,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,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,2,2,2,2,2,2,2,2,+ 82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,+ 82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,+ 82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,+ 82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,+};++KBTS_INLINE kbts_u8 kbts__GetUnicodeFlags(kbts_u32 Codepoint)+{+ return (Codepoint < 1114110) ? kbts__UnicodeFlags_Data[((kbts_un)kbts__UnicodeFlags_PageIndices[Codepoint/128] * 128) | (Codepoint & 127)] : 0;+}++static kbts_u8 kbts__UnicodeBidirectionalClass_PageIndices[8703] = {+ 0,1,2,2,2,3,4,5,2,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,+ 29,30,2,2,31,32,33,34,35,2,2,2,2,36,37,38,39,40,41,42,43,44,45,46,47,48,2,49,2,2,50,51,+ 52,53,54,55,56,57,58,59,57,60,57,57,57,61,57,57,2,2,57,57,57,57,57,57,2,62,63,64,57,57,57,57,+ 65,66,67,68,69,70,71,72,73,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,74,73,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,75,+ 2,2,2,2,2,2,2,2,2,76,2,2,77,78,79,80,81,82,83,84,85,86,87,88,73,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,89,73,57,57,57,57,57,75,90,73,57,57,57,57,57,57,75,+ 73,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,75,2,2,91,92,93,94,95,95,96,97,98,99,100,101,+ 102,103,104,105,57,106,107,108,2,109,110,111,2,2,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,+ 130,131,132,133,134,135,136,137,138,139,57,140,141,142,143,57,144,145,146,147,148,149,150,151,152,153,154,155,57,156,157,158,+ 2,2,2,2,2,2,2,159,160,2,161,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,162,+ 2,2,2,2,2,2,2,2,163,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,103,2,2,2,2,164,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,165,57,57,57,57,57,57,57,57,57,57,57,57,57,2,2,2,2,166,167,168,169,57,57,170,57,171,172,173,174,+ 73,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,175,2,2,2,2,2,2,2,2,2,176,177,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,178,+ 2,2,179,2,2,180,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,181,182,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,183,57,57,57,57,184,161,+ 2,185,186,187,188,189,190,57,191,192,193,2,2,194,195,196,2,2,2,2,197,198,57,57,57,57,57,57,57,57,199,57,+ 200,201,202,57,57,203,57,57,57,204,57,205,57,57,57,206,207,208,209,57,57,57,57,57,210,211,212,57,213,214,57,57,+ 57,57,215,216,217,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,218,57,57,57,57,57,57,57,57,+ 73,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,219,73,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,220,57,221,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,222,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,223,57,57,57,57,224,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,2,2,2,2,225,57,57,57,57,57,57,57,57,57,57,57,+ 73,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,226,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,227,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 228,57,229,230,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 73,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,231,+ 73,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+ 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,+};++static kbts_u8 kbts__UnicodeBidirectionalClass_Data[29696] = {+ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,9,9,9,0,0,0,0,0,8,10,8,10,10,7,7,7,7,7,7,7,7,7,7,10,0,0,0,0,0,+ 0,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,0,0,0,0,0,0,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,0,0,0,0,1,+ 1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,10,0,9,9,9,9,0,0,0,0,2,0,0,1,0,0,9,9,7,7,0,2,0,0,0,7,2,0,0,0,0,0,+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,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,2,0,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,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,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,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,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,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,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,2,2,2,2,+ 2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,+ 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2,2,2,2,0,0,2,2,0,0,2,2,2,2,0,2,+ 0,0,0,0,0,0,2,0,2,2,2,0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,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,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,+ 2,2,2,4,4,4,4,4,4,4,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,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,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,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,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,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,2,2,2,2,2,2,2,2,0,0,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,2,2,2,2,2,2,2,2,2,+ 2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,9,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,+ 3,4,4,3,4,4,3,4,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,0,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,+ 6,6,6,6,6,6,0,0,5,9,9,5,10,5,0,0,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,6,6,6,6,6,6,6,6,6,6,9,6,6,5,5,5,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,6,0,4,4,4,4,4,4,5,5,4,4,0,4,4,4,4,5,5,7,7,7,7,7,7,7,7,7,7,5,5,5,5,5,5,+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,5,5,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,+ 4,4,4,4,4,4,4,4,4,4,4,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,3,3,0,0,0,0,3,0,0,4,3,3,+ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,3,4,4,4,4,4,4,4,4,4,3,4,4,4,3,4,4,4,4,4,0,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,+ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,0,0,3,0,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,6,6,0,0,0,0,0,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,6,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,+ 4,4,4,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,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,4,2,4,2,2,2,+ 2,4,4,4,4,4,4,4,4,2,2,2,2,4,2,2,2,4,4,4,4,4,4,4,2,2,2,2,2,2,2,2,2,2,4,4,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,4,2,2,0,2,2,2,2,2,2,2,2,0,0,2,2,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,0,2,0,0,0,2,2,2,2,0,0,4,2,2,2,+ 2,4,4,4,4,0,0,2,2,0,0,2,2,4,2,0,0,0,0,0,0,0,0,2,0,0,0,0,2,2,0,2,2,2,4,4,0,0,2,2,2,2,2,2,2,2,2,2,2,2,9,9,2,2,2,2,2,2,2,9,2,2,4,0,+ 0,4,4,2,0,2,2,2,2,2,2,0,0,0,0,2,2,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,0,2,2,0,2,2,0,2,2,0,0,4,0,2,2,+ 2,4,4,0,0,0,0,4,4,0,0,4,4,4,0,0,0,4,0,0,0,0,0,0,0,2,2,2,2,0,2,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,4,4,2,2,2,4,2,0,0,0,0,0,0,0,0,0,+ 0,4,4,2,0,2,2,2,2,2,2,2,2,2,0,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,0,2,2,0,2,2,2,2,2,0,0,4,2,2,2,+ 2,4,4,4,4,4,0,4,4,2,0,2,2,4,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,4,4,0,0,2,2,2,2,2,2,2,2,2,2,2,9,0,0,0,0,0,0,0,2,4,4,4,4,4,4,+ 0,4,2,2,0,2,2,2,2,2,2,2,2,0,0,2,2,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,0,2,2,0,2,2,2,2,2,0,0,4,2,2,4,+ 2,4,4,4,4,0,0,2,2,0,0,2,2,4,0,0,0,0,0,0,0,4,4,2,0,0,0,0,2,2,0,2,2,2,4,4,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,+ 0,0,4,2,0,2,2,2,2,2,2,0,0,0,2,2,2,0,2,2,2,2,0,0,0,2,2,0,2,0,2,2,0,0,0,2,2,0,0,0,2,2,2,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,2,2,+ 4,2,2,0,0,0,2,2,2,0,2,2,2,4,0,0,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,9,0,0,0,0,0,0,+ 4,2,2,2,4,2,2,2,2,2,2,2,2,0,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,4,2,4,4,+ 4,2,2,2,2,0,4,4,4,0,4,4,4,4,0,0,0,0,0,0,0,4,4,0,2,2,2,0,0,2,0,0,2,2,4,4,0,0,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,2,+ 2,4,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,0,0,4,2,2,2,+ 2,2,2,2,2,0,2,2,2,0,2,2,4,4,0,0,0,0,0,0,0,2,2,0,0,0,0,0,0,2,2,0,2,2,4,4,0,0,2,2,2,2,2,2,2,2,2,2,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,+ 4,4,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,0,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,2,2,2,2,2,2,2,2,2,2,2,4,4,2,2,2,+ 2,4,4,4,4,0,2,2,2,0,2,2,2,4,2,2,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,4,0,0,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,+ 0,4,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,0,2,0,0,+ 2,2,2,2,2,2,2,0,0,0,4,0,0,0,0,2,2,2,4,4,4,0,4,0,2,2,2,2,2,2,2,2,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,+ 0,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,2,2,4,4,4,4,4,4,4,0,0,0,0,9,+ 2,2,2,2,2,2,2,4,4,4,4,4,4,4,4,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,2,2,0,2,0,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,0,2,2,2,2,2,2,2,2,2,2,4,2,2,4,4,4,4,4,4,4,4,4,2,0,0,+ 2,2,2,2,2,0,2,0,4,4,4,4,4,4,4,0,2,2,2,2,2,2,2,2,2,2,0,0,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,4,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,4,2,4,2,4,0,0,0,0,2,2,+ 2,2,2,2,2,2,2,2,0,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,2,2,2,2,2,2,0,0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2,+ 4,4,4,4,4,2,4,4,2,2,2,2,2,4,4,4,4,4,4,4,4,4,4,4,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,2,2,+ 2,2,2,2,2,2,4,2,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,4,4,4,2,4,4,4,4,4,4,2,4,4,2,2,4,4,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,4,4,2,2,2,2,4,4,4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,4,4,4,2,2,2,2,2,2,2,2,2,2,2,+ 2,2,4,2,2,4,4,2,2,2,2,2,2,4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,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,2,2,2,2,+ 2,2,2,2,2,2,0,2,0,0,0,0,0,2,0,0,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,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,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,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,2,0,2,2,2,2,0,0,2,2,2,2,2,2,2,0,2,0,2,2,2,2,0,0,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,2,2,+ 2,2,2,2,2,2,2,2,2,0,2,2,2,2,0,0,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,2,2,2,0,2,2,2,2,0,0,2,2,2,2,2,2,2,0,+ 2,0,2,2,2,2,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,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,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,0,2,2,2,2,0,0,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,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,2,2,2,2,2,2,2,0,0,4,4,4,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,0,0,0,+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,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,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,0,0,2,2,2,2,2,2,0,0,+ 0,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,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,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,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,2,2,2,2,2,2,2,+ 0,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,0,0,0,0,0,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,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,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,0,0,0,0,0,0,0,+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,4,4,2,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,4,2,2,2,0,0,0,0,0,0,0,0,0,+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,4,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,0,4,4,0,0,0,0,0,0,0,0,0,0,0,0,+ 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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,4,2,4,4,4,4,4,4,4,2,2,+ 2,2,2,2,2,2,4,2,2,4,4,4,4,4,4,4,4,4,4,4,2,2,2,2,2,2,2,9,2,4,0,0,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,4,4,4,1,4,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,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,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,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,0,0,0,0,0,0,0,+ 2,2,2,2,2,4,4,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,2,2,2,2,4,2,0,0,0,0,0,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,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,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,+ 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,2,0,4,4,4,2,2,2,2,4,4,2,2,2,0,0,0,0,2,2,4,2,2,2,2,2,2,4,4,4,0,0,0,0,+ 0,0,0,0,0,0,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,2,2,2,2,2,2,2,2,2,2,0,0,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,+ 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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,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,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,4,2,2,4,0,0,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,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,4,2,4,4,4,4,4,4,4,0,4,2,4,2,2,4,4,4,4,4,4,4,4,2,2,2,2,2,2,4,4,4,4,4,4,4,4,4,4,0,0,4,+ 2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,+ 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 4,4,4,4,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,2,4,4,4,4,4,2,4,2,2,2,+ 2,2,4,2,2,2,2,2,2,2,2,2,2,0,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,4,4,4,4,4,4,4,4,4,2,2,2,2,2,2,2,2,2,2,2,2,+ 4,4,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,2,2,4,4,4,4,2,2,4,4,2,4,4,4,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,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,4,2,4,4,2,2,2,4,2,4,4,4,2,2,0,0,0,0,0,0,0,0,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,4,4,4,4,4,4,4,2,2,4,4,0,0,0,2,2,2,2,2,+ 2,2,2,2,2,2,2,2,2,2,0,0,0,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,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,2,2,0,0,0,0,0,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,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,2,2,+ 2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,4,4,4,2,4,4,4,4,4,4,4,4,4,4,4,4,4,2,4,4,4,4,4,4,4,2,2,2,2,4,2,2,2,2,2,2,4,2,2,2,4,4,2,0,0,0,0,0,+ 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,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,2,2,2,2,+ 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,2,2,2,2,2,0,0,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,2,2,+ 2,2,2,2,2,2,0,0,2,2,2,2,2,2,0,0,2,2,2,2,2,2,2,2,0,2,0,2,0,2,0,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,2,0,0,+ 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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,0,2,0,+ 0,0,2,2,2,0,2,2,2,2,2,2,2,0,0,0,2,2,2,2,0,0,2,2,2,2,2,2,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,2,2,2,0,2,2,2,2,2,2,2,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,1,1,1,2,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,9,9,9,9,9,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,10,0,0,0,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,0,0,0,0,0,1,1,1,1,1,1,7,2,0,0,7,7,7,7,7,7,8,8,0,0,0,2,+ 7,7,7,7,7,7,7,7,7,7,8,8,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,+ 9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,2,0,0,0,0,2,0,0,2,2,2,2,2,2,2,2,2,2,0,2,0,0,0,2,2,2,2,2,0,0,0,0,0,0,2,0,2,0,2,0,2,2,2,2,9,2,2,2,2,2,2,2,2,2,2,2,0,0,2,2,2,2,+ 0,0,0,0,0,2,2,2,2,2,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,2,2,+ 2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,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,2,2,2,2,2,2,2,2,2,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,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,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 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,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,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,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,2,2,2,2,4,4,4,2,2,0,0,0,0,0,0,0,0,0,0,0,0,+ 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,2,2,2,2,2,2,2,2,0,2,0,0,0,0,0,2,0,0,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,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,0,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,0,+ 2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,+ 0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,4,4,4,4,2,2,0,2,2,2,2,2,0,0,2,2,2,2,2,0,0,0,+ 0,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,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,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,0,0,4,4,0,0,2,2,2,0,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,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,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,0,2,2,2,2,+ 0,0,0,0,0,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,2,2,2,2,2,2,2,2,2,2,2,2,2,0,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,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,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,2,2,2,2,0,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,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,2,2,+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,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,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,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,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,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,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,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,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,2,2,2,2,2,2,2,2,2,0,0,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,2,0,+ 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,+ 2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,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,2,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,4,4,4,0,4,4,4,4,4,4,4,4,4,4,0,0,+ 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,4,4,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,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,4,2,2,2,2,2,2,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,+ 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,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,2,2,2,2,+ 2,2,2,2,2,2,2,2,0,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,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,2,2,2,2,2,2,2,2,2,0,0,2,2,0,2,0,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,+ 2,2,4,2,2,2,4,2,2,2,2,4,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,4,4,2,0,0,0,0,4,0,0,0,2,2,2,2,2,2,2,2,9,9,0,0,0,0,0,0,+ 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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,+ 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,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,2,2,2,2,+ 2,2,2,2,4,4,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2,2,2,2,2,2,2,2,2,2,2,2,2,4,+ 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,2,2,2,2,2,2,2,2,4,4,4,4,4,4,4,4,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,4,4,4,4,4,4,4,4,4,4,4,2,2,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,+ 4,4,4,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,2,2,4,4,4,4,2,2,4,4,2,2,+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,2,2,2,2,2,2,2,4,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,0,+ 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,2,2,2,2,2,2,2,2,2,2,2,4,4,4,4,4,4,2,2,4,4,2,2,4,4,0,0,0,0,0,0,0,0,0,+ 2,2,2,4,2,2,2,2,2,2,2,2,4,2,0,0,2,2,2,2,2,2,2,2,2,2,0,0,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,2,2,4,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,2,4,4,4,2,2,4,4,2,2,2,2,2,4,4,+ 2,4,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,4,2,2,2,2,2,2,2,2,4,0,0,0,0,0,0,0,0,0,+ 0,2,2,2,2,2,2,0,0,2,2,2,2,2,2,0,0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,0,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,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,0,0,0,0,0,0,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,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,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,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,4,2,2,4,2,2,2,2,4,0,0,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,+ 2,2,2,2,2,2,2,0,0,0,0,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,+ 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,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,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,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,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,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,0,0,0,0,0,3,4,3,3,3,3,3,3,3,3,3,3,8,3,3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,3,3,3,0,3,0,+ 3,3,0,3,3,0,3,3,3,3,3,3,3,3,3,3,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,+ 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,10,0,0,10,0,0,0,0,0,0,0,0,0,9,0,0,8,8,0,0,0,0,0,9,9,0,0,0,0,0,5,5,5,5,5,0,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,1,+ 0,0,0,9,9,9,0,0,0,0,0,8,10,8,10,10,7,7,7,7,7,7,7,7,7,7,10,0,0,0,0,0,0,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,0,0,0,0,0,+ 0,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,0,0,0,0,0,0,0,0,0,0,0,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,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,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,0,+ 0,0,2,2,2,2,2,2,0,0,2,2,2,2,2,2,0,0,2,2,2,2,2,2,0,0,2,2,2,0,0,0,9,9,0,0,0,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 2,2,2,2,2,2,2,2,2,2,2,2,0,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,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,0,2,+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 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,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,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,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,2,2,2,0,0,0,0,0,+ 2,0,2,0,0,0,0,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,2,2,2,2,2,2,2,2,2,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,0,0,+ 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,0,0,0,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,2,2,+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,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,0,0,0,0,+ 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,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,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,2,2,2,2,2,2,2,2,4,4,4,4,4,0,0,0,0,0,+ 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,0,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,2,2,2,+ 2,2,2,2,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 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,0,0,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,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,2,2,2,2,2,2,0,0,0,0,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,2,2,2,2,2,2,0,0,0,0,+ 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,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,+ 2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,0,2,2,0,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,0,2,2,0,0,0,+ 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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,+ 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,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,0,0,0,0,0,0,0,0,0,+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 2,2,2,2,2,2,0,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,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 3,3,3,3,3,3,0,0,3,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,0,0,0,3,0,0,3,+ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,+ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,0,0,0,0,0,3,3,3,3,3,+ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,0,0,3,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,0,3,3,3,3,+ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,+ 3,4,4,4,0,4,4,0,0,0,0,0,4,4,4,4,3,3,3,3,0,3,3,3,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,4,4,4,0,0,0,0,4,+ 3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,+ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,0,0,0,0,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,+ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,+ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,0,0,3,3,3,3,3,3,3,3,+ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,+ 3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,3,3,3,3,3,3,+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,0,0,0,0,0,0,0,0,6,6,6,6,6,6,6,6,6,6,0,0,0,0,0,0,+ 6,6,6,6,6,6,6,6,6,6,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,4,4,4,4,4,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,+ 3,3,3,3,3,3,0,0,0,0,0,0,0,0,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,0,+ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,4,4,3,0,0,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,+ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,+ 3,3,4,4,4,4,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,+ 3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,+ 2,4,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,4,4,4,4,4,4,4,+ 4,4,4,4,4,4,4,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,4,2,2,4,4,2,0,0,0,0,0,0,0,0,0,4,+ 4,4,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,4,4,4,2,2,4,4,2,2,2,2,2,+ 2,2,4,0,0,0,0,0,0,0,0,0,0,2,0,0,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,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,+ 4,4,4,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,2,2,2,2,2,2,4,4,4,4,4,2,4,4,4,4,4,4,4,4,0,2,2,2,2,2,2,2,2,2,2,+ 2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,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,2,2,2,2,2,4,2,2,2,0,0,0,0,0,0,0,0,0,+ 4,4,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,4,4,4,4,4,4,4,4,2,+ 2,2,2,2,2,2,2,2,2,4,4,4,4,2,2,4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,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,4,4,4,2,2,4,2,4,4,2,2,2,2,2,2,4,2,+ 2,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 2,2,2,2,2,2,2,0,2,0,2,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,2,2,2,4,4,4,4,4,4,4,4,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,+ 4,4,2,2,0,2,2,2,2,2,2,2,2,0,0,2,2,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,0,2,2,0,2,2,2,2,2,0,4,4,2,2,2,+ 4,2,2,2,2,0,0,2,2,0,0,2,2,2,0,0,2,0,0,0,0,0,0,2,0,0,0,0,0,2,2,2,2,2,2,2,0,0,4,4,4,4,4,4,4,0,0,0,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,+ 2,2,2,2,2,2,2,2,2,2,0,2,0,0,2,0,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,2,2,2,2,2,2,2,2,0,2,2,2,2,4,4,4,4,4,+ 4,0,2,0,0,2,0,2,2,2,2,0,2,2,4,2,4,2,4,2,2,2,0,2,2,0,0,0,0,0,0,0,0,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 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,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,4,4,4,4,4,4,4,4,+ 2,2,4,4,4,2,4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,4,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,4,4,4,4,4,2,4,2,2,2,2,4,+ 4,2,4,4,2,2,2,2,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,4,4,4,0,0,2,2,2,2,4,4,2,4,+ 4,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,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,4,4,4,4,4,4,4,2,2,4,2,4,+ 4,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 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,2,2,2,2,2,2,2,2,2,2,2,2,2,4,2,4,2,2,4,4,4,4,4,4,2,4,2,2,0,0,0,0,0,0,+ 2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 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,0,0,4,2,4,2,2,4,4,4,4,2,4,4,4,4,4,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,+ 2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,4,4,4,4,4,4,4,4,2,4,4,2,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,2,+ 2,2,2,2,2,2,2,0,0,2,0,0,2,2,2,2,2,2,2,2,0,2,2,0,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,0,2,2,0,0,4,4,2,4,2,+ 2,2,2,4,2,2,2,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,0,0,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,2,2,2,2,2,2,2,2,2,2,2,2,4,4,4,4,0,0,4,4,2,2,2,2,4,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 2,4,4,4,4,4,4,2,2,4,4,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,2,2,2,2,2,2,2,2,2,2,4,4,4,4,4,4,2,2,4,4,4,4,2,+ 2,2,2,2,2,2,2,4,0,0,0,0,0,0,0,0,2,4,4,4,4,4,4,2,2,4,4,4,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,2,2,2,2,2,2,+ 2,2,2,2,2,2,2,2,2,2,4,4,4,4,4,4,4,4,4,4,4,4,4,2,4,4,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,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,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,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,+ 2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 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,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,+ 2,2,2,2,2,2,2,2,2,0,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,2,2,2,2,2,2,2,2,4,4,4,4,4,4,4,0,4,4,4,4,4,4,2,2,+ 2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,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,0,0,0,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,2,2,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,2,4,4,4,4,4,4,4,2,4,4,2,4,4,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 2,2,2,2,2,2,2,0,2,2,0,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,2,2,2,2,2,2,2,2,4,4,4,4,4,4,0,0,0,4,0,4,4,0,4,+ 4,4,4,4,4,4,2,4,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,2,2,2,2,2,2,0,2,2,0,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,2,2,2,2,2,2,2,0,4,4,0,2,2,4,2,4,2,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,4,2,2,2,2,0,0,0,0,0,0,0,+ 4,4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,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,2,2,2,2,2,2,4,4,4,4,4,0,0,0,2,2,+ 4,2,4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,9,9,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 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,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,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,+ 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,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,2,2,2,2,+ 2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,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,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,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 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,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,2,2,2,2,+ 4,2,2,2,2,2,2,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,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,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,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,2,2,2,2,2,2,+ 2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 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,4,4,4,4,4,4,4,4,4,4,4,4,2,2,2,4,4,4,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 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,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,0,0,0,0,0,0,0,+ 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,2,0,2,2,2,2,2,2,2,2,2,2,0,0,0,0,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,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,+ 2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,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,0,0,4,4,4,4,4,2,0,0,0,0,0,0,0,0,0,0,+ 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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,4,4,4,4,4,4,2,2,2,2,2,2,2,2,2,+ 2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,2,2,2,+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 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,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,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 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,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,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,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 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,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,2,2,2,2,+ 2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,4,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,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,0,0,0,0,0,0,0,4,4,4,4,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,0,2,4,0,0,0,0,0,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,+ 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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,+ 2,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,0,2,2,2,2,2,2,2,0,2,2,0,+ 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,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,0,0,0,0,0,0,0,0,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,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,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,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,+ 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,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,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,+ 2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,0,0,2,4,4,2,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,7,7,7,7,7,7,7,7,7,7,0,0,0,0,0,0,+ 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,+ 4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,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,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,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,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,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,+ 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,2,2,2,2,2,2,2,2,2,0,0,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,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,2,2,4,4,4,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,4,4,4,4,4,+ 4,4,4,2,2,4,4,4,4,4,4,4,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,4,4,4,4,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,+ 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,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,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,0,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,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,2,2,2,2,2,2,2,2,2,2,2,0,2,2,0,0,2,0,0,2,2,0,0,2,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,0,2,0,2,2,2,+ 2,2,2,2,0,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,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,2,2,2,2,2,0,2,2,2,2,0,0,2,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,0,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,0,2,2,2,2,0,+ 2,2,2,2,2,0,2,0,0,0,2,2,2,2,2,2,2,0,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,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,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,0,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,0,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,2,0,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,0,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,2,0,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,0,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,2,0,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,0,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,2,0,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,0,2,2,2,2,2,2,2,2,0,0,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,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,+ 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2,2,2,2,4,4,4,4,4,+ 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2,2,2,2,2,2,2,2,4,2,2,2,2,2,2,2,2,2,2,+ 2,2,2,2,4,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 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,2,0,0,0,0,0,0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 4,4,4,4,4,4,4,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,4,4,4,4,4,4,4,0,4,4,0,4,4,4,4,4,0,0,0,0,0,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,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,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,4,4,4,4,4,4,4,2,2,2,2,2,2,2,0,0,+ 2,2,2,2,2,2,2,2,2,2,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,4,4,4,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,9,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,4,4,4,4,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,4,4,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,2,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,0,2,2,2,2,0,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,+ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,+ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,+ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,+ 3,3,3,3,3,0,0,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,+ 3,3,3,3,4,4,4,4,4,4,4,3,0,0,0,0,3,3,3,3,3,3,3,3,3,3,0,0,0,0,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 5,5,5,5,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,5,5,0,5,0,0,5,0,5,5,5,5,5,5,5,5,5,5,0,5,5,5,5,0,5,0,5,0,0,0,0,+ 0,0,5,0,0,0,0,5,0,5,0,5,0,5,5,5,0,5,5,0,5,0,0,5,0,5,0,5,0,5,0,5,0,5,5,0,5,0,0,5,5,5,5,0,5,5,5,5,5,5,5,0,5,5,5,5,0,5,5,5,5,0,5,0,+ 5,5,5,5,5,5,5,5,5,5,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,5,5,5,0,5,5,5,5,5,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,0,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,2,0,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,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,0,0,0,0,0,0,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,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,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,+ 2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,7,7,7,7,7,7,7,7,7,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,+ 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,+ 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,+ 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,+ 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,+};++KBTS_INLINE kbts_u8 kbts__GetUnicodeBidirectionalClass(kbts_u32 Codepoint)+{+ return (Codepoint < 1114110) ? kbts__UnicodeBidirectionalClass_Data[((kbts_un)kbts__UnicodeBidirectionalClass_PageIndices[Codepoint/128] * 128) | (Codepoint & 127)] : 0;+}++static kbts_u8 kbts__UnicodeJoiningType_PageIndices[8703] = {+ 0,1,0,0,0,0,2,0,0,3,0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,+ 25,26,0,0,0,0,27,0,0,0,0,0,0,0,28,29,30,31,32,0,33,34,35,36,37,38,0,39,0,0,0,0,+ 40,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,42,43,44,0,0,0,0,+ 45,46,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,47,48,0,0,49,50,51,52,53,54,0,55,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,56,0,0,0,0,0,57,43,0,58,+ 0,0,0,59,0,60,61,0,0,0,0,0,0,0,0,0,0,0,0,0,62,63,0,64,0,0,65,0,0,66,67,68,+ 69,70,71,72,73,74,75,76,77,78,0,79,80,81,82,0,83,0,84,85,86,87,0,0,88,89,90,91,0,92,93,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,94,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,95,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,96,97,0,0,0,0,0,0,0,98,99,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,101,0,+ 0,0,102,103,104,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,105,106,0,0,0,0,0,0,0,0,0,0,+ 107,108,97,0,0,109,0,0,0,110,0,111,0,0,0,0,0,112,113,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 114,0,115,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+};++static kbts_u8 kbts__UnicodeJoiningType_Data[14848] = {+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,5,+ 0,5,5,0,5,5,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,0,5,0,0,0,2,0,4,4,4,4,2,4,2,4,2,2,2,2,2,4,4,4,4,2,2,2,2,2,2,2,2,2,2,2,2,2,+ 3,2,2,2,2,2,2,2,4,2,2,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,5,4,4,4,0,4,4,4,2,2,2,2,2,2,2,2,+ 2,2,2,2,2,2,2,2,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,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,2,2,2,2,2,2,2,2,+ 4,2,2,4,4,4,4,4,4,4,4,4,2,4,2,4,2,2,4,4,0,4,5,5,5,5,5,5,5,0,0,5,5,5,5,5,5,0,0,5,5,0,5,5,5,5,4,4,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,2,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,4,5,2,2,2,4,4,4,4,4,2,2,2,2,4,2,2,2,2,2,2,2,2,2,4,2,4,2,4,2,2,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,5,5,5,5,5,5,5,5,0,0,4,2,2,2,2,2,2,2,2,2,2,2,4,4,4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,4,2,2,2,2,4,2,4,4,2,2,2,4,4,2,2,2,2,2,2,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,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,2,2,2,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,3,0,0,5,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,0,5,5,5,5,5,5,5,5,5,0,5,5,5,0,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 4,2,2,2,2,2,4,4,2,4,2,2,2,2,2,2,2,2,2,2,4,2,4,4,4,5,5,5,0,0,0,0,2,0,2,2,2,2,0,4,2,4,4,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,+ 4,4,4,3,3,3,2,0,0,2,2,2,2,2,4,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,2,2,2,2,2,2,2,2,2,2,4,4,4,0,4,2,2,4,4,2,2,2,2,2,2,4,2,2,2,2,2,2,+ 2,2,2,2,2,2,2,2,2,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,5,0,0,0,+ 0,5,5,5,5,5,5,5,5,0,0,0,0,5,0,0,0,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,+ 0,5,5,5,5,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,+ 0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,+ 0,5,5,0,0,0,0,5,5,0,0,5,5,5,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,5,0,0,0,0,0,0,0,0,0,0,+ 0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,+ 0,5,5,5,5,5,0,5,5,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,+ 0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,5,+ 0,5,5,5,5,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 5,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 5,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,5,5,+ 5,0,0,0,0,0,5,5,5,0,5,5,5,5,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,5,+ 0,0,0,0,0,0,5,0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,+ 0,5,5,5,5,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,5,5,5,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,5,5,5,5,5,5,5,0,0,0,0,0,+ 0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,5,5,5,5,5,5,5,5,5,0,0,0,+ 0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,5,0,5,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,+ 5,5,5,5,5,0,5,5,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,+ 0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,0,5,5,5,5,5,5,0,5,5,0,0,5,5,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,5,0,0,5,5,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,5,5,5,5,5,5,5,0,0,+ 0,0,0,0,0,0,5,0,0,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,2,0,0,3,5,5,5,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,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,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,0,0,0,0,0,0,0,+ 0,0,0,0,0,5,5,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,2,2,2,2,5,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,5,5,5,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,5,5,5,5,5,5,5,0,5,0,5,0,0,5,5,5,5,5,5,5,5,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,0,0,5,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,5,5,5,5,5,0,5,0,0,0,+ 0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,+ 5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,0,0,5,5,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,5,5,0,0,0,5,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,0,0,5,5,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,0,5,5,5,5,5,5,5,5,5,5,5,5,5,0,5,5,5,5,5,5,5,0,0,0,0,5,0,0,0,0,0,0,5,0,0,0,5,5,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 0,0,0,0,0,0,0,0,0,0,0,5,0,3,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,0,0,0,0,0,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,0,5,5,5,5,5,5,5,5,5,5,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,5,0,0,0,5,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,5,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,5,5,5,5,0,0,5,5,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,0,0,5,5,0,0,5,5,0,0,0,0,0,0,0,0,0,+ 0,0,0,5,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,5,5,5,0,0,5,5,0,0,0,0,0,5,5,+ 0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,5,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,0,0,0,0,0,+ 0,5,5,5,0,5,5,0,0,0,0,0,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,0,0,0,0,5,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 2,2,2,2,2,4,0,4,0,4,4,0,0,1,4,4,4,4,4,2,2,2,2,1,2,2,2,2,2,4,2,2,2,4,0,0,4,5,5,0,0,0,0,2,2,2,2,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 2,4,2,4,4,4,2,2,2,4,2,2,4,2,4,4,2,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,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,2,2,2,4,2,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,4,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,4,2,2,2,2,2,2,2,2,2,2,2,2,+ 2,2,2,2,2,0,5,5,5,5,5,5,5,5,5,5,5,2,2,2,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,4,4,2,2,2,2,2,2,2,2,2,2,+ 2,2,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,2,2,4,4,4,0,2,4,4,2,2,4,2,2,+ 0,2,4,4,2,0,0,0,0,4,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,+ 5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,5,5,0,0,0,0,0,0,0,0,0,0,5,+ 5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,0,0,5,5,0,0,0,0,0,+ 0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,0,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,+ 5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,0,+ 0,0,0,0,0,0,0,0,0,5,5,5,5,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,0,0,5,0,5,5,0,0,0,0,0,0,5,0,+ 0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,+ 5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,0,0,0,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,+ 5,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,5,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,+ 0,0,5,5,5,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,0,5,0,0,0,0,5,+ 5,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,0,0,0,0,0,0,5,5,0,5,+ 5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,0,0,5,0,5,+ 5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,5,0,0,5,5,5,5,5,5,0,5,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,5,0,0,5,5,5,5,0,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,0,5,5,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,5,0,+ 0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,0,0,5,5,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,0,0,5,5,5,5,0,+ 0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,0,5,5,5,5,5,5,0,5,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,5,5,5,5,5,5,5,0,5,5,0,5,5,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,0,0,0,5,0,5,5,0,5,+ 5,5,5,5,5,5,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,5,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,+ 5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,0,0,0,0,0,+ 5,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,0,0,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,5,5,5,5,5,+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 5,5,5,5,5,5,5,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,5,5,5,5,5,5,5,0,5,5,0,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 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,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,2,2,2,2,+ 2,2,2,2,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,+};++KBTS_INLINE kbts_u8 kbts__GetUnicodeJoiningType(kbts_u32 Codepoint)+{+ return (Codepoint < 1114110) ? kbts__UnicodeJoiningType_Data[((kbts_un)kbts__UnicodeJoiningType_PageIndices[Codepoint/128] * 128) | (Codepoint & 127)] : 0;+}++static kbts_u8 kbts__UnicodeCombiningClass_PageIndices[8703] = {+ 0,0,0,0,0,0,1,0,0,2,0,3,4,5,6,7,8,9,10,11,12,12,12,13,14,12,15,16,17,18,19,20,+ 21,22,0,0,0,0,23,0,0,0,0,0,0,0,24,25,0,26,27,0,28,29,30,31,32,33,0,34,0,0,0,0,+ 0,35,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,37,38,0,0,0,0,+ 39,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,41,42,0,0,43,44,45,46,0,47,0,48,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,49,0,0,0,0,0,50,0,0,0,+ 0,0,0,51,0,52,53,0,0,0,0,0,0,0,0,0,0,0,0,0,54,55,0,0,0,0,56,0,0,57,58,59,+ 60,61,62,63,64,65,66,67,68,69,0,70,71,72,73,0,61,0,74,75,76,77,0,0,71,0,78,79,0,0,80,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,81,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,82,83,0,0,0,0,0,0,0,0,84,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,85,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,86,87,88,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 89,90,83,0,0,91,0,0,0,92,0,93,0,0,0,0,0,94,95,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+};++static kbts_u8 kbts__UnicodeCombiningClass_Data[12288] = {+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,232,220,220,220,220,232,216,220,220,220,220,220,202,202,220,220,220,220,202,202,220,220,220,220,220,220,220,220,220,220,220,1,1,1,1,1,220,220,220,220,230,230,230,+ 230,230,230,230,230,240,230,220,220,220,230,230,230,220,220,0,230,230,230,220,220,220,220,230,232,220,220,230,233,234,234,233,234,234,233,230,230,230,230,230,230,230,230,230,230,230,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,230,230,230,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,220,230,230,230,230,220,230,230,230,222,220,230,230,230,230,230,230,220,220,220,220,220,220,230,230,220,230,230,222,228,230,22,15,16,17,23,18,19,20,21,14,14,24,12,25,0,13,+ 0,10,11,0,230,220,0,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,230,230,230,230,230,230,31,32,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,28,29,30,31,32,33,27,34,230,230,220,220,230,230,230,230,230,220,230,230,220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,35,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,230,230,230,230,230,0,0,230,230,230,230,220,230,0,0,230,230,0,220,230,230,220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,220,230,230,220,230,230,220,220,220,230,220,220,230,220,230,+ 230,230,220,230,220,230,220,230,220,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,230,230,230,230,230,220,230,0,0,0,0,0,0,0,0,0,220,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,230,230,0,230,230,230,230,230,230,230,230,230,0,230,230,230,0,230,230,230,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,220,220,220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,220,220,220,230,230,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,230,230,230,230,230,220,220,220,220,220,230,230,230,230,230,230,230,230,230,230,230,230,230,230,0,220,230,230,220,230,230,220,230,230,230,220,220,220,28,29,30,230,230,230,220,230,230,220,220,230,230,230,230,230,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,230,220,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,4,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,9,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,107,107,107,107,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,118,118,9,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,122,122,122,122,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,220,220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,220,0,220,0,127,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,129,132,0,131,0,0,0,0,0,132,132,132,132,0,0,+ 132,0,230,230,9,0,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,254,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,9,9,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,228,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,222,230,220,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,254,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,230,230,230,230,230,230,0,0,220,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,230,230,230,220,220,220,220,220,220,230,230,220,0,220,+ 220,230,230,220,220,230,230,230,230,230,220,230,230,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,220,230,230,230,230,230,230,230,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,9,9,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,230,0,1,220,220,220,220,220,230,230,220,220,220,220,230,0,1,1,1,1,1,1,1,0,0,0,0,220,0,0,0,0,0,0,230,0,0,0,230,230,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 230,230,220,230,230,230,230,230,230,230,220,230,230,234,214,220,202,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,232,228,228,220,218,230,233,220,230,220,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,1,1,230,230,230,230,1,1,1,230,230,0,0,0,0,230,0,0,0,1,1,230,220,230,1,1,220,220,220,220,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,218,228,232,222,224,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,0,0,0,0,230,230,230,230,230,230,230,230,230,230,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,220,220,220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,+ 9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,0,230,230,220,0,0,230,230,0,0,0,0,0,230,230,+ 0,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,230,230,230,230,230,220,220,220,220,220,220,220,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,220,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,230,230,230,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,220,0,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,1,220,0,0,0,0,9,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,230,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,220,220,220,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,220,220,230,230,230,220,230,220,220,220,220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,230,220,230,220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,7,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 230,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 9,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,7,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,7,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,230,230,230,230,230,0,0,0,230,230,230,230,230,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,9,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,9,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,+ 7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,7,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9,0,+ 0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,7,0,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,230,230,230,230,230,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,216,216,1,1,1,0,0,0,226,216,216,216,216,216,0,0,0,0,0,0,0,0,220,220,220,220,220,+ 220,220,220,0,0,230,230,230,230,230,220,220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,230,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 230,230,230,230,230,230,230,0,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,0,0,230,230,230,230,230,230,230,0,230,230,0,230,230,230,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,232,232,220,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,220,220,220,220,220,220,220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,230,230,230,230,230,230,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+};++KBTS_INLINE kbts_u8 kbts__GetUnicodeCombiningClass(kbts_u32 Codepoint)+{+ return (Codepoint < 1114110) ? kbts__UnicodeCombiningClass_Data[((kbts_un)kbts__UnicodeCombiningClass_PageIndices[Codepoint/128] * 128) | (Codepoint & 127)] : 0;+}++static kbts_u16 kbts__UnicodeParentInfo_PageIndices[34815] = {+ 0,1,2,3,0,4,5,6,7,0,8,9,0,10,0,11,0,12,0,0,13,14,0,0,15,0,0,0,16,17,18,0,+ 19,20,21,22,0,0,23,24,0,0,0,0,0,0,25,26,0,27,28,0,0,0,29,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,30,31,0,0,0,32,33,0,34,35,0,0,0,0,0,0,0,36,37,0,0,0,38,0,+ 0,0,39,0,0,40,41,0,0,0,38,0,0,0,42,0,0,0,0,0,0,0,0,0,0,0,43,44,45,46,0,0,+ 0,47,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,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,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,49,50,51,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,52,53,54,0,55,56,0,57,58,59,60,0,61,62,63,+ 64,0,0,0,0,0,0,0,0,0,0,0,65,0,66,0,67,68,69,70,71,72,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,73,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 74,0,75,76,77,75,76,78,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,79,80,81,0,82,0,0,0,0,0,0,0,0,0,0,0,0,0,0,83,0,0,0,0,84,0,0,0,+ 0,85,0,86,0,0,87,88,89,90,0,0,0,0,0,0,0,91,0,92,0,0,0,93,94,0,95,0,96,0,0,0,+ 97,0,98,0,0,0,0,0,0,99,0,0,100,0,0,0,0,0,0,0,0,101,0,0,102,0,0,0,0,0,0,103,+ 104,105,106,0,107,0,0,108,0,109,0,0,0,0,0,0,110,111,0,0,0,112,0,0,113,114,115,0,0,0,116,0,+ 117,0,0,118,0,0,0,0,0,119,120,121,0,0,122,123,0,124,0,0,0,125,126,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,128,0,0,0,129,0,130,0,0,0,131,0,0,0,0,132,0,+ 0,0,0,0,0,0,133,134,0,0,135,0,0,0,0,0,136,137,138,0,139,140,141,142,0,0,0,143,144,145,0,0,+ 146,147,0,148,149,0,150,151,0,0,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,0,0,170,171,+ 172,173,174,175,176,177,0,178,179,0,180,181,182,183,184,185,186,0,187,188,0,0,0,189,190,0,0,0,191,0,192,193,+ 194,195,196,0,0,197,198,199,200,201,202,203,0,0,204,205,206,207,0,208,0,209,0,0,210,211,0,0,212,0,213,214,+ 215,216,0,217,218,0,219,0,220,0,221,222,0,223,0,224,0,225,0,226,0,227,228,229,230,231,232,233,234,235,236,237,+ 238,0,0,239,240,0,241,242,243,0,244,245,246,247,248,249,250,251,252,0,0,253,254,255,0,256,257,258,259,260,261,262,+ 263,264,265,266,267,0,268,0,0,0,269,270,271,0,272,273,274,0,275,276,277,278,279,280,281,282,283,284,285,0,0,286,+ 287,0,288,0,289,290,0,0,291,0,292,0,0,293,0,294,295,0,0,0,0,296,297,0,298,299,300,301,302,303,0,0,+ 0,0,304,305,306,307,308,309,310,311,312,313,314,0,315,316,317,318,0,319,320,321,322,0,323,324,0,325,0,0,326,327,+ 328,329,330,331,332,333,334,0,0,0,335,336,337,0,338,0,339,340,341,342,343,344,345,346,0,347,0,348,349,350,351,0,+ 352,353,354,355,356,0,357,0,358,359,360,361,0,0,0,362,363,0,364,365,0,0,366,367,368,0,369,0,370,371,0,0,+ 0,0,372,373,374,0,375,376,0,377,378,379,380,381,382,383,384,0,385,0,386,387,388,389,0,390,0,0,0,0,391,0,+ 0,392,0,393,394,395,396,397,398,399,400,401,0,402,403,404,405,406,407,0,0,0,0,0,0,408,0,409,410,411,0,412,+ 413,0,414,415,416,417,0,0,418,419,0,0,0,0,420,421,422,0,0,423,424,425,0,426,427,428,429,430,0,431,432,433,+ 0,434,435,0,0,0,0,436,437,0,0,438,0,0,439,440,441,442,443,444,445,446,0,447,448,449,0,450,451,452,0,453,+ 454,0,455,456,0,0,457,458,459,0,460,461,462,0,0,0,0,0,0,0,0,463,464,465,466,467,468,0,469,0,0,0,+ 0,0,470,0,0,471,472,0,473,0,0,474,0,475,476,477,0,0,0,0,0,0,478,0,0,479,0,480,481,482,0,0,+ 0,483,0,484,485,0,486,487,488,0,0,489,490,491,492,0,0,493,0,494,0,0,495,0,496,0,497,0,0,0,0,498,+ 499,0,0,0,0,0,0,0,0,0,0,0,500,501,0,0,0,502,503,504,505,506,507,508,0,509,510,0,0,0,511,512,+ 513,514,515,0,0,0,0,516,0,517,0,0,0,518,519,520,0,0,0,521,0,0,0,0,522,0,0,523,0,0,0,0,+ 0,0,524,0,0,0,0,525,0,0,0,526,0,527,0,528,529,0,0,530,531,532,533,534,535,536,537,0,538,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,539,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,540,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,541,542,0,0,0,543,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,33,0,544,0,545,0,+ 0,0,0,0,0,546,0,0,0,0,0,0,0,23,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,547,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,548,549,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,550,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,551,0,0,552,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,553,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,554,555,556,0,0,0,0,0,0,557,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 558,0,0,0,0,0,559,0,0,0,0,0,0,0,0,0,0,560,0,0,0,0,0,0,0,0,0,561,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,562,0,0,0,0,0,0,0,0,0,0,0,0,0,563,0,564,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,565,0,0,0,0,0,0,0,0,0,566,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,567,0,0,0,0,0,0,568,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,569,0,0,0,0,0,0,0,0,0,0,0,0,570,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,571,0,0,0,0,0,0,0,0,0,+ 0,0,572,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,573,0,0,0,0,0,0,574,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 575,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,576,0,0,0,0,577,0,578,0,579,0,+ 0,0,0,580,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,581,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,582,0,0,0,0,0,0,0,0,0,0,0,0,0,0,583,0,0,584,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,585,0,0,586,0,0,0,0,0,0,0,0,0,0,0,0,0,587,0,0,0,588,0,589,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,590,0,0,0,591,0,0,0,0,0,592,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,593,0,0,0,0,0,0,0,0,594,0,0,0,0,0,0,+ 595,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,596,0,0,597,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,598,0,0,+ 0,0,599,0,0,0,0,600,601,602,0,0,0,0,0,0,0,0,603,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 604,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,605,0,0,606,0,607,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,608,0,0,0,0,0,0,0,0,0,609,0,0,0,0,0,0,0,610,0,0,+ 0,0,0,0,611,0,612,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,613,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,614,0,0,615,616,0,0,0,617,0,0,618,0,0,0,0,0,0,+ 0,0,0,0,0,0,619,0,0,620,0,0,0,621,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,622,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,623,0,0,0,0,0,0,+ 0,624,0,0,0,0,625,0,0,0,0,626,0,0,0,0,0,0,0,0,0,0,0,0,0,627,0,0,0,628,0,0,+ 0,0,0,0,0,0,629,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,630,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,631,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,632,0,0,0,0,0,633,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,634,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,635,0,0,636,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,637,638,0,0,0,0,0,0,0,0,0,639,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,640,+ 0,0,0,0,0,0,0,0,0,0,0,641,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,642,0,0,0,643,0,644,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 645,0,0,0,646,0,0,0,0,0,0,0,0,647,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,648,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,649,0,650,0,0,0,0,0,0,0,651,0,0,0,652,0,0,0,0,0,0,0,653,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,654,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+};++static kbts_u32 kbts__UnicodeParentInfo_Data[20960] = {+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66400,66423,66421,66422,0,+ 0,1048664,197177,328094,393598,1114167,66418,459018,459046,983176,65810,393556,393562,197183,590017,1048696,131720,0,524539,459032,459067,1245203,131728,393604,131730,590026,393592,0,0,0,0,0,+ 66420,1048648,197171,328084,393586,1114150,66417,459011,524515,917655,131704,328109,393538,197180,590008,1048680,131414,0,524499,459025,524523,1245184,131724,459060,131726,655525,393580,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,197174,0,0,0,0,0,0,0,0,0,0,0,66419,0,0,66399,0,0,0,0,0,0,0,0,+ 0,0,262650,0,66396,131722,131706,65959,0,0,262654,0,0,0,0,66416,0,0,0,0,262658,197168,66398,0,66397,0,0,0,262626,0,0,0,+ 0,0,262638,0,66019,66395,131702,66415,0,0,262642,0,0,0,0,65963,0,0,0,0,262646,197165,66186,0,65816,0,0,0,262622,0,0,0,+ 0,0,262634,262634,0,0,0,0,0,0,0,0,0,0,0,0,0,0,131716,131716,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,131718,131718,0,0,0,0,0,0,0,0,0,0,0,0,66412,66412,0,0,0,0,+ 66183,66183,0,0,0,0,0,0,66413,66413,66413,66413,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66414,+ 328104,328104,0,0,0,0,0,0,0,0,0,0,0,0,0,328099,328099,0,0,0,0,0,0,66381,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,65936,65936,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,66367,66367,66405,66405,0,0,0,0,65936,65936,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66366,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66393,0,0,0,0,0,0,+ 65973,65973,0,0,0,0,0,0,66384,0,0,0,0,0,0,0,0,0,0,66379,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,66409,65949,0,65829,66406,65873,0,66411,0,66408,66410,65867,459053,0,0,0,262618,0,328089,0,459039,0,0,0,0,0,262610,+ 0,66407,0,0,0,393544,0,0,0,393550,0,0,131708,66403,131710,66404,65948,524531,0,0,0,262606,0,393568,0,589999,0,0,0,0,0,262630,+ 0,131714,0,0,0,524507,0,0,0,393574,197129,197132,66401,66402,131712,0,0,0,131471,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,65935,0,0,0,0,0,0,0,0,0,131227,0,0,66371,0,197150,131700,65953,262594,0,65945,0,0,0,66394,0,+ 0,0,0,262586,0,0,0,65595,0,0,0,65595,0,65630,0,0,131696,0,0,66376,0,197162,131698,65943,262602,0,66377,0,0,0,66392,0,+ 0,0,0,262614,0,0,0,65578,0,0,0,65578,0,65614,0,0,0,0,0,0,0,0,65935,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65936,65936,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65936,65936,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,65936,65936,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,197216,131836,66134,66134,66134,131828,66134,0,66134,131820,66134,131826,66134,0,66134,0,+ 66134,66134,0,66134,131822,0,66134,66134,66134,197204,66134,0,0,0,0,0,0,0,66855,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,197135,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,66370,0,66370,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,65935,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65935,0,0,65978,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66387,66387,66387,0,0,0,0,66385,0,0,0,+ 0,66383,66383,0,0,0,0,0,65935,0,0,66380,0,0,0,66379,0,0,0,65935,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66379,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,131474,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66387,66387,0,0,0,0,66385,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,66380,0,0,0,0,0,0,65935,0,0,0,0,0,65931,0,0,0,0,0,0,0,+ 0,66383,66383,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,197147,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,131507,65934,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,65936,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65935,+ 0,0,0,0,0,0,197138,0,0,0,65935,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,197141,0,0,65935,0,0,0,+ 66378,0,65935,0,0,0,0,0,0,0,0,0,65935,0,0,0,0,65935,0,0,0,0,65935,0,0,0,0,65935,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,197153,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66378,0,65935,0,0,0,0,0,0,0,0,0,65935,0,0,0,+ 0,65935,0,0,0,0,65935,0,0,0,0,65935,0,0,0,0,0,0,66368,66369,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,65935,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,328074,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,65935,0,65935,0,65935,0,65935,0,65935,0,0,0,65935,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65935,0,65935,0,65936,65936,+ 0,0,65935,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65936,65936,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65936,65936,0,0,0,0,+ 0,0,65755,65755,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 131694,131694,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66087,66087,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,66158,66158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 262598,262598,65609,65609,65609,65609,65609,65609,262598,262598,65609,65609,65609,65609,65609,65609,131506,131506,0,0,0,0,0,0,131506,131506,0,0,0,0,0,0,+ 262590,262590,65985,65985,65985,65985,65985,65985,262590,262590,65985,65985,65985,65985,65985,65985,197042,197042,0,0,0,0,0,0,197042,197042,0,0,0,0,0,0,+ 131506,131506,0,0,0,0,0,0,131506,131506,0,0,0,0,0,0,197042,197042,0,0,0,0,0,0,0,197042,0,0,0,0,0,0,+ 262578,262578,65973,65973,65973,65973,65973,65973,262578,262578,65973,65973,65973,65973,65973,65973,66386,0,0,0,66388,0,0,0,0,0,0,0,66391,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65935,0,0,0,0,0,0,0,0,197159,+ 0,0,0,0,0,0,65935,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65935,0,0,0,0,0,0,0,197126,0,+ 0,0,65931,65931,0,0,0,0,0,0,0,0,0,0,0,0,65935,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66374,0,66373,0,66375,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65930,0,65930,0,66372,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,65935,0,0,0,0,65935,0,0,65935,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,65935,0,65935,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65894,0,0,0,+ 0,0,0,65935,0,65936,0,0,65935,0,0,0,0,66376,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,65935,0,0,66158,66158,0,0,0,0,0,0,0,0,0,0,0,0,65936,65936,0,0,65936,65936,0,0,65755,65755,66390,66390,0,0,+ 0,0,65936,65936,0,0,65936,65936,0,0,0,0,0,0,0,0,0,66389,66389,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,66374,0,0,0,0,0,65894,65894,0,65934,0,0,0,0,0,0,66382,66382,66382,66382,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65932,0,0,+ 0,0,0,0,0,0,0,0,66365,66365,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,66388,0,0,0,0,65935,0,65935,0,65935,0,65935,0,65935,0,65935,0,65935,0,65935,0,65935,0,65935,0,65935,+ 0,65935,0,0,65935,0,65935,0,65935,0,0,0,0,0,0,131471,0,0,131471,0,0,131471,0,0,131471,0,0,131471,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65935,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65756,65756,65756,65756,0,0,0,0,0,0,0,0,0,0,65935,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67213,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67212,0,67214,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67211,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67210,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,67209,0,0,0,0,0,0,0,0,0,0,0,0,0,67208,0,0,0,+ 0,67207,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67206,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,67205,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67204,0,0,0,+ 0,0,0,0,0,0,0,67203,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,67202,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67201,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67200,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,67199,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,67198,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,67197,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,67196,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67195,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,67194,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,131892,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67193,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,67192,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67191,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67190,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,67189,0,0,0,0,0,0,0,0,0,0,0,131890,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67188,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67187,0,0,0,+ 0,0,0,0,0,0,0,0,67186,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66821,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,131888,0,0,0,0,0,0,+ 0,0,0,0,0,0,67185,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67184,0,0,0,0,0,0,0,0,0,+ 0,0,0,67183,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67182,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,67181,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,67180,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 67179,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,67178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67177,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67176,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67175,0,0,0,67172,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,67174,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,67173,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,67171,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67170,0,0,+ 0,67169,0,0,0,0,0,0,0,0,0,67168,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67167,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67166,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67165,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67164,0,+ 0,0,0,0,0,0,0,67163,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67162,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,67161,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,67160,0,0,0,0,0,0,0,67159,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67158,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67157,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,67156,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,67155,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,67154,0,0,0,0,0,0,0,0,0,0,67153,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67152,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,66809,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,66810,0,0,0,0,0,0,0,0,0,0,0,66804,0,0,0,0,0,67151,66806,0,0,0,67150,0,0,+ 0,67149,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,66801,0,0,0,66807,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,66803,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 66808,0,0,0,0,0,0,0,0,0,0,0,67148,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,66802,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 67147,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 66805,0,0,0,0,0,66798,0,0,0,0,66800,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,131886,0,0,0,0,0,0,0,0,0,0,0,0,67146,0,0,0,66797,+ 0,0,67145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,66799,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67144,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67143,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67140,0,0,0,0,0,0,0,0,0,0,66790,0,0,0,0,0,+ 0,0,0,0,0,0,0,131882,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 66789,0,0,0,0,66794,0,0,0,0,0,0,0,131878,0,0,0,0,0,0,67138,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,67136,0,0,67137,66793,66782,0,0,0,66788,0,0,0,0,0,0,0,0,0,67135,0,0,0,0,0,0,0,0,+ 66791,0,0,0,0,0,0,0,0,0,0,0,0,67134,0,0,0,0,67142,0,0,67141,0,67133,0,0,0,0,0,0,0,0,+ 0,0,0,0,67132,0,0,0,0,0,0,0,67131,0,0,0,0,0,0,0,0,131876,0,66775,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,66779,0,0,66778,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66776,0,66785,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67130,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,67129,0,0,0,131874,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66777,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,66780,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66781,67128,0,0,0,0,+ 0,0,0,0,0,0,67127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67126,0,0,0,0,67125,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,66774,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66772,0,0,0,0,+ 0,0,0,66773,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67139,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,131872,0,131870,0,0,0,0,0,0,0,0,66769,0,0,0,0,0,0,0,0,0,0,0,66768,0,+ 0,0,0,0,131866,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66770,0,0,0,0,131864,0,0,0,0,0,+ 0,0,0,0,0,67124,67124,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,131862,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66771,+ 0,0,0,0,0,0,0,0,0,67123,0,0,0,0,0,0,0,131860,0,0,0,0,0,0,0,0,67122,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67121,0,66764,0,0,0,0,0,0,0,66154,0,197225,+ 0,0,0,66765,0,0,0,0,0,0,67120,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67119,+ 0,0,0,0,0,66760,0,0,0,0,0,67118,0,0,0,0,0,67117,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,67116,0,0,0,0,0,0,0,0,66766,0,0,0,0,0,0,0,0,0,0,0,0,0,66767,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67115,0,0,0,0,0,0,0,+ 0,0,66763,0,0,0,0,0,67114,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,67113,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67112,0,+ 0,0,67112,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66318,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67111,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67110,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67109,0,66761,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,67108,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,131884,0,0,66757,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,131854,0,0,0,131800,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,67107,0,0,0,0,0,0,0,67106,0,0,0,0,0,0,0,0,0,0,0,0,+ 66759,0,67105,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,66264,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,131852,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67104,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,66758,0,0,0,0,0,0,0,0,0,0,0,67103,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66754,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67101,67102,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,67100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,67099,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67098,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,67097,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67096,67095,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 66752,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,131798,0,0,0,66747,0,+ 0,0,0,0,0,0,0,0,66750,0,0,0,67094,0,0,0,0,0,0,66751,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66746,0,0,0,0,0,0,66745,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,67091,0,0,0,67093,0,0,0,0,67092,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,67090,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67089,0,0,0,0,0,+ 0,0,67088,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,66749,0,0,0,66741,0,0,0,0,0,0,0,0,66740,0,0,66748,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,67087,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66743,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67085,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,67084,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67083,0,0,0,0,+ 0,0,0,0,0,0,0,67082,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,66744,0,0,0,67081,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67086,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,67080,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,66739,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,131880,0,+ 0,0,0,0,0,66738,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,67079,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67078,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,197222,0,0,0,0,0,0,66314,0,0,0,0,67077,0,0,0,0,0,0,0,0,0,0,0,67076,+ 0,0,0,0,0,0,67075,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,67074,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66735,+ 67072,0,66733,0,66737,66734,0,0,0,0,0,0,0,0,131850,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,67071,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 67070,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66731,0,0,0,0,0,0,+ 0,0,0,67069,0,0,0,0,0,0,0,0,0,0,0,0,66729,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,67068,0,0,67067,0,0,0,0,0,0,0,0,0,0,0,0,0,67066,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67073,0,0,0,0,0,0,0,66730,0,0,0,0,0,+ 0,67065,67065,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67064,0,0,+ 0,0,0,0,0,0,0,0,67063,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67062,0,0,+ 0,0,0,0,0,0,0,0,0,67061,0,0,0,0,0,0,0,0,0,0,66723,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,66726,0,0,0,0,0,0,0,0,0,67060,0,0,67059,0,0,67058,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,66722,131848,0,0,0,0,0,0,0,66728,66725,0,0,0,0,0,66727,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,66720,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67057,0,+ 0,0,0,0,66718,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,131868,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67054,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,67056,0,0,0,0,0,0,66724,0,67055,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,66719,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67053,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,66715,0,0,0,66721,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,67052,0,0,0,0,0,0,0,0,0,67051,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66714,0,0,0,67050,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66711,0,0,0,0,0,0,0,0,0,66713,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66717,0,0,0,0,0,0,0,0,0,0,+ 0,67049,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,131846,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,67048,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66714,0,0,0,0,0,0,0,+ 0,66709,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,66712,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,66707,0,0,0,67047,0,0,0,131858,0,131844,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 66710,0,0,0,0,0,0,0,66708,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67046,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,197219,0,66705,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,67045,0,0,0,0,0,0,0,0,0,0,67044,0,0,67043,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67042,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,197213,0,0,0,131842,0,0,0,0,0,0,0,0,0,+ 66703,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67041,0,0,0,0,0,0,0,0,0,0,67040,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,66704,0,0,0,0,0,66706,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67039,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67038,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,66693,0,0,0,0,0,66696,0,0,0,66701,67037,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67036,0,66695,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67035,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67034,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,67033,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66690,0,0,0,0,+ 0,0,0,67032,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 66689,0,0,0,0,0,0,0,0,67031,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,66699,67030,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,67029,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66694,0,0,0,+ 0,0,67028,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66692,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,67027,0,0,0,0,0,0,0,0,0,0,0,0,0,67026,0,0,0,0,0,0,67025,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66687,0,0,67024,0,0,+ 0,0,0,0,66685,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,131840,0,0,0,0,0,0,66688,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,67023,0,0,0,0,0,0,0,0,0,0,0,66681,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66682,0,0,0,0,0,0,+ 0,0,0,0,0,66678,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,66684,67022,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66679,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,67021,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,131790,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,66675,0,0,0,0,0,0,0,0,131834,0,0,0,0,0,0,0,0,0,0,67020,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66677,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,66674,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66670,0,0,0,67019,0,0,0,0,0,0,0,+ 67019,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,197210,0,0,0,131832,0,0,0,0,+ 0,67018,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,66673,0,0,0,0,67017,0,0,66676,0,0,0,0,0,0,0,67016,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66671,0,0,0,0,+ 0,0,0,0,0,67015,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66672,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66668,0,0,0,0,0,0,67014,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66666,0,0,0,0,0,0,0,67013,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67012,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,66664,0,0,0,131830,0,0,0,0,0,0,0,0,67011,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,66665,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67010,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,67009,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,67008,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,67007,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,197201,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66663,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,67006,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66661,0,0,0,0,0,0,0,67005,0,0,0,0,+ 0,0,0,0,66659,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,67004,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67003,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67002,0,0,0,0,66658,0,66662,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67001,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,66657,0,0,0,0,0,0,0,0,0,0,0,197198,66128,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,67000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,66999,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,66654,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66998,+ 0,0,0,0,0,0,0,0,0,0,0,0,66651,66997,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,66655,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66996,0,0,0,0,66647,0,0,66653,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66995,0,0,0,0,0,0,0,0,0,66994,0,+ 0,197195,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,66993,66645,0,0,0,0,0,0,0,0,0,0,0,0,131824,66992,0,0,0,0,0,0,0,+ 0,0,0,0,0,66991,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,66648,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66643,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,66646,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66990,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66649,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66989,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,66988,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66641,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66642,0,0,0,0,0,+ 0,0,0,0,0,0,0,66987,0,0,0,131818,0,0,0,0,0,66637,0,0,0,0,0,0,0,0,0,66644,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66638,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,131788,66639,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,66986,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,66985,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,66633,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66635,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66984,0,0,131816,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66983,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,66982,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66977,0,0,0,0,0,0,66981,0,0,0,0,0,66980,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66634,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,66979,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,66631,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66629,0,0,0,0,0,0,+ 0,0,0,0,0,66978,0,0,0,66630,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,131780,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66976,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,66627,0,66628,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66624,0,0,0,0,0,0,0,0,0,0,66623,0,0,0,0,+ 0,0,0,0,0,0,0,0,66975,0,0,66628,0,0,0,0,0,0,0,0,0,131814,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66974,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,66622,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 66973,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66972,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66626,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 66625,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66620,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,131774,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66621,0,0,0,0,66971,0,0,0,0,0,+ 0,0,0,0,0,0,0,131772,0,0,0,66970,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,66969,0,0,0,0,0,0,0,0,0,0,0,0,66618,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66610,0,+ 0,0,0,0,0,0,66616,0,0,66615,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,66619,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,66968,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66967,0,0,0,+ 0,0,0,0,0,0,0,0,0,66611,0,0,0,0,0,0,0,131812,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,66966,0,0,0,66609,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66612,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,66965,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,66614,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,66964,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66613,0,0,66963,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66606,0,0,0,0,0,0,+ 0,0,0,0,0,66605,0,0,0,0,0,0,0,0,0,0,131810,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,66604,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66962,0,0,0,0,0,0,0,0,0,0,0,0,66608,0,66607,+ 0,0,66602,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,66598,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,131766,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66603,0,0,0,0,+ 0,0,0,0,0,0,0,66596,0,0,0,0,0,0,0,0,0,0,0,0,131808,0,0,0,0,0,0,0,0,0,0,0,+ 0,66597,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66320,131856,+ 66601,0,0,0,0,0,0,0,0,0,131806,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,66961,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,66599,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,66960,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,66594,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,131792,0,0,0,0,66595,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,66583,0,131802,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66582,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,66580,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66587,0,66592,0,+ 0,0,0,0,0,0,0,0,66591,66590,0,0,0,0,0,0,66589,0,0,0,0,0,131794,0,0,0,0,0,0,66588,66585,0,+ 0,0,0,0,0,66584,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66575,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,66586,66586,131786,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,66579,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,66576,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,66959,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66574,0,0,0,+ 131784,0,0,0,0,0,0,0,0,0,66958,0,0,0,0,66957,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,66577,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66578,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,66573,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,66956,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 66572,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 131760,0,0,0,0,0,66955,0,0,66954,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66570,0,+ 66564,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66571,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66569,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66568,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66953,0,0,0,66566,0,0,0,0,0,0,0,0,0,+ 0,0,0,66952,0,0,0,66562,66951,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 66950,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66563,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,66560,0,0,0,0,0,0,0,0,0,0,0,0,66559,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66567,0,0,0,0,+ 0,0,0,66949,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 66557,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66556,0,+ 0,0,0,0,0,0,0,66948,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,197192,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,66947,0,0,0,0,0,0,66561,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66554,0,0,0,0,0,0,0,0,+ 0,66558,0,0,0,66946,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66555,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66553,0,0,0,0,0,0,66551,66945,0,0,0,0,0,+ 0,0,0,0,0,66548,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66944,0,0,0,0,66549,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66550,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66943,0,0,0,0,0,+ 0,66546,0,0,0,197189,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,66547,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 66942,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66545,66941,0,0,0,0,0,0,0,0,0,0,0,0,0,66543,0,+ 0,0,0,0,0,0,0,0,0,0,0,66544,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,66937,0,0,0,0,66940,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,66939,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66938,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66538,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,66540,0,0,0,0,66542,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,131838,0,0,66936,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66541,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66537,0,0,0,0,0,0,0,0,0,131756,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,66935,0,0,0,0,0,66934,0,0,0,0,0,0,0,0,0,0,0,66933,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66932,0,66931,0,0,0,0,0,0,0,0,0,66930,0,0,+ 0,0,0,0,0,131782,66929,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66928,0,0,+ 0,0,0,66927,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66536,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66539,66926,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,66925,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,66924,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66923,0,0,+ 0,0,0,0,0,0,0,0,0,66534,66922,0,66921,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66920,0,0,0,+ 0,0,0,0,0,0,0,66919,0,0,0,0,0,0,0,66535,0,66533,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66531,0,0,+ 0,0,0,0,0,0,0,0,0,66532,0,0,0,0,0,0,0,0,0,0,0,0,0,131778,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,66529,0,0,66918,0,66917,0,0,0,0,0,0,0,0,66530,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66916,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,66915,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,66525,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66527,0,0,0,0,0,+ 0,0,0,0,0,0,66524,0,0,0,0,0,0,0,0,0,0,0,66528,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,66523,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66522,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66914,0,0,0,0,0,0,0,0,0,0,0,131776,0,0,0,+ 0,0,0,0,0,0,0,66913,0,66912,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,66911,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,66910,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,66909,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,66908,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,66907,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,66906,0,0,0,0,0,0,0,0,0,0,0,0,0,131770,0,0,0,0,0,0,+ 0,0,0,0,0,0,66905,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66518,0,0,0,0,0,+ 0,66904,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,66903,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66514,+ 0,0,0,0,0,0,0,0,0,0,0,0,66520,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 66902,0,0,66901,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,66512,0,0,0,0,0,0,0,0,0,0,0,0,66515,0,0,0,0,0,0,0,66900,0,0,0,0,0,0,66899,0,+ 0,66513,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66510,0,66898,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66517,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,66519,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,66507,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,66516,0,0,0,0,66511,0,0,0,0,0,0,0,0,0,0,131754,0,0,0,0,0,0,0,0,0,+ 66897,0,0,0,0,0,0,0,0,0,131746,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66509,+ 0,0,0,0,0,0,0,0,0,0,0,66508,0,0,0,0,0,0,66506,0,0,0,66504,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,131768,0,0,0,0,0,0,0,0,0,0,131750,0,0,0,0,0,131744,0,+ 0,131752,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,131748,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66505,0,0,0,0,0,0,0,+ 66502,0,0,0,0,0,0,0,0,0,131764,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,66500,0,0,0,0,0,0,0,0,0,0,0,0,66896,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,66895,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,66894,66499,0,0,0,0,0,66497,0,0,0,0,0,0,0,0,0,0,66501,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,131742,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66893,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66892,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66891,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,66890,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66496,66889,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,66490,0,0,0,0,0,0,0,0,0,66888,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,66492,0,0,0,66493,0,0,0,0,0,0,0,0,0,0,0,0,0,131762,0,0,66495,0,0,0,0,+ 0,0,66489,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66887,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66488,0,0,0,0,0,66494,0,0,0,0,0,0,0,0,0,+ 0,0,0,66487,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,131740,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66491,0,0,0,0,0,0,0,0,0,66485,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66481,0,0,0,0,66886,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,66480,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66486,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66885,0,0,0,0,0,0,0,0,0,0,0,66483,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66884,0,0,0,0,0,0,0,0,0,66883,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,66475,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66484,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66477,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,66478,0,0,66475,0,66473,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66474,0,0,0,66882,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66479,0,0,0,0,0,66881,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66880,66880,0,0,0,0,0,0,0,+ 0,0,0,0,66470,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,66472,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66879,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66878,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,66877,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,66465,0,0,0,0,0,0,0,0,0,66876,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,66463,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,66457,0,66464,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66454,0,0,66461,0,0,0,66466,0,0,0,+ 0,0,0,0,0,0,66460,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,66459,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66462,66456,0,0,0,0,0,0,0,+ 0,0,0,66875,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,66458,131738,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66453,66451,0,0,0,0,0,0,0,0,+ 0,0,0,66874,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66450,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,66452,0,0,0,0,0,0,0,0,0,0,0,0,0,131736,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66455,0,0,0,0,+ 66873,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,131734,+ 0,0,0,0,0,0,0,0,0,0,0,197207,0,0,0,0,0,0,0,0,0,0,0,0,66449,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,66872,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,131732,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66448,0,+ 0,0,66871,0,0,0,0,0,0,0,0,0,0,0,0,66447,0,0,0,0,0,0,0,0,0,0,0,0,66446,0,0,0,+ 0,0,0,0,0,0,0,0,66445,66870,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,66869,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,66868,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66444,0,0,0,0,0,0,0,0,0,0,0,0,66867,0,+ 0,0,0,0,0,0,0,0,0,0,66443,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,131758,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66441,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 66866,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66440,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66865,0,0,+ 0,0,0,0,0,0,0,66864,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66439,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66435,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66434,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66432,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66433,0,0,0,0,0,0,0,66437,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66863,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,66431,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66862,0,0,0,0,66861,0,+ 0,0,0,0,0,66860,0,0,0,0,0,0,0,0,0,66859,0,0,0,0,0,0,66858,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66857,0,0,0,0,+ 0,0,0,66438,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,66430,66436,0,0,0,0,0,0,0,0,0,0,0,0,0,197186,0,0,0,+ 0,0,0,0,0,0,0,0,0,131692,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65888,0,0,0,0,0,0,0,66374,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65935,0,65935,0,0,0,0,+ 0,0,0,0,0,65755,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65930,65930,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,65935,0,65935,0,0,0,0,0,0,65933,0,0,0,0,65935,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,197156,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,197144,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65933,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,262582,0,+ 0,131512,65894,0,0,0,0,0,0,65779,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,65755,0,0,0,65935,0,65935,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65977,65977,0,0,0,0,0,0,328079,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65936,65936,131506,131506,0,0,0,+ 0,0,66856,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66853,0,0,0,+ 0,0,0,0,0,66854,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,66852,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66850,0,0,0,0,0,+ 0,0,0,0,66851,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66849,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,66848,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,66847,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,66846,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,66845,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,66844,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,66843,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66842,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,66841,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,66840,0,66840,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,66838,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66839,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,131804,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66837,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,66364,0,0,0,0,0,66363,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,66836,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66835,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,66834,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66830,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66833,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66832,0,0,0,0,0,0,0,0,66831,0,0,0,+ 0,0,0,66829,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66362,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,66828,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,66827,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,66826,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,66825,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66824,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66823,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66822,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66820,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66819,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,66818,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,66817,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,66361,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,66816,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,66815,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66814,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66813,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66812,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66811,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,66796,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66795,0,0,0,0,0,0,0,+ 0,0,0,0,66792,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66787,66786,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66784,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66783,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,66360,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66762,0,0,+ 0,0,0,0,0,0,66756,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66755,0,0,0,0,0,+ 0,0,0,0,0,66753,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66742,0,0,0,+ 0,0,0,0,0,0,0,131796,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,66736,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 66732,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66359,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,66716,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66698,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,66702,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,66700,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66697,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66691,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66686,0,0,0,0,0,+ 0,0,0,66683,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,66680,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,66669,0,0,0,0,0,0,0,0,0,0,0,0,0,66667,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66660,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66656,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66652,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,66650,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,66640,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66636,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66632,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,66617,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,66600,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,66593,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,66581,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,66565,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66358,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66552,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66528,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,66526,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,66521,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66503,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66498,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,66482,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66471,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66476,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,66469,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66468,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66467,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66442,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,66429,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,66428,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,66427,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66426,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66425,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 66424,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+};++KBTS_INLINE kbts_u32 kbts__GetUnicodeParentInfo(kbts_u32 Codepoint)+{+ return (Codepoint < 1114110) ? kbts__UnicodeParentInfo_Data[((kbts_un)kbts__UnicodeParentInfo_PageIndices[Codepoint/32] * 32) | (Codepoint & 31)] : 0;+}++static kbts_u8 kbts__UnicodeUseClass_PageIndices[4351] = {+ 0,1,1,1,1,1,2,3,4,5,6,7,8,9,10,11,12,1,1,1,1,1,1,13,14,15,16,17,18,19,1,1,+ 20,1,1,1,1,21,1,22,1,1,1,1,1,23,24,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,25,26,27,28,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,29,1,1,1,1,30,31,1,32,33,34,35,36,37,38,39,40,41,42,43,44,45,1,46,47,48,49,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,50,50,50,50,51,50,50,50,50,50,50,50,50,50,50,50,+ 50,50,50,52,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,53,1,1,1,1,1,1,1,1,54,55,1,56,1,57,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,58,59,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,60,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,61,62,1,63,64,1,1,1,65,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+};++static kbts_u8 kbts__UnicodeUseClass_Data[16896] = {+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,0,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,0,21,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,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,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,1,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,29,29,29,29,29,29,29,29,29,0,0,0,0,0,0,1,0,0,29,0,0,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,9,9,9,0,0,0,0,1,0,1,1,1,1,0,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,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,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 29,29,29,31,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,34,36,9,1,36,33,+ 36,35,35,35,35,34,34,34,34,36,36,36,36,3,33,36,0,29,30,0,0,34,35,35,1,1,1,1,1,1,1,1,1,1,35,35,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 2,29,31,31,0,1,1,1,1,1,1,1,1,0,0,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,0,0,0,1,1,1,1,0,0,9,1,36,33,+ 36,35,35,35,35,0,0,33,33,0,0,33,33,3,0,0,0,0,0,0,0,0,0,36,0,0,0,0,1,1,0,1,1,1,35,35,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,0,6,0,+ 0,29,29,31,0,1,1,1,1,1,1,0,0,0,0,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,0,1,1,0,1,1,0,0,9,0,36,33,+ 36,35,35,0,0,0,0,34,34,0,0,34,34,3,0,0,0,30,0,0,0,0,0,0,0,1,1,1,1,0,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,29,8,2,2,0,12,0,0,0,0,0,0,0,0,0,0,+ 0,29,29,31,0,1,1,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,0,9,1,36,33,+ 36,35,35,35,35,34,0,34,34,34,0,36,36,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,35,35,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,29,8,29,8,8,8,+ 0,29,31,31,0,1,1,1,1,1,1,1,1,0,0,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,0,9,1,36,34,+ 36,35,35,35,35,0,0,33,33,0,0,33,33,3,0,0,0,0,0,0,0,34,34,34,0,0,0,0,1,1,0,1,1,1,35,35,0,0,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,29,0,0,1,1,1,1,1,1,0,0,0,1,1,1,0,1,1,1,1,0,0,0,1,1,0,1,0,1,1,0,0,0,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,36,36,+ 34,36,36,0,0,0,33,33,33,0,33,33,33,3,0,0,0,0,0,0,0,0,0,36,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 29,31,31,31,29,1,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,9,1,34,34,+ 34,36,36,36,36,0,34,34,34,0,34,34,34,3,0,0,0,0,0,0,0,34,35,0,1,1,1,0,0,0,0,0,1,1,35,35,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1,29,31,31,0,1,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,0,9,1,36,34,+ 34,36,36,36,36,0,34,34,34,0,34,34,34,3,0,0,0,0,0,0,0,36,36,0,0,0,0,0,0,0,1,0,1,1,35,35,0,0,1,1,1,1,1,1,1,1,1,1,0,37,37,31,0,0,0,0,0,0,0,0,0,0,0,0,+ 29,29,31,31,1,1,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,34,34,1,36,36,+ 36,35,35,35,35,0,33,33,33,0,33,33,33,3,38,0,0,0,0,0,0,0,0,36,0,0,0,0,0,0,0,1,1,1,35,35,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,29,31,31,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,0,1,0,0,+ 1,1,1,1,1,1,1,0,0,0,4,0,0,0,0,36,36,36,34,34,35,0,35,0,36,33,33,33,33,33,33,36,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,36,36,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,34,1,1,34,34,34,34,35,35,35,0,0,0,0,0,+ 1,1,1,1,1,1,0,34,29,29,29,29,8,29,34,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,1,1,0,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1,0,1,34,1,1,34,34,34,34,35,35,35,34,12,1,0,0,+ 1,1,1,1,1,0,0,0,29,29,29,29,0,29,6,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,1,0,6,0,6,0,8,0,0,0,0,0,0,+ 1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,9,35,34,34,35,34,34,34,34,35,35,35,35,29,0,+ 35,34,29,29,35,0,29,29,1,1,1,1,1,7,7,7,7,7,7,7,7,7,7,7,0,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,7,7,7,7,0,0,0,+ 0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,36,36,34,34,35,35,33,34,34,34,34,29,30,31,6,34,13,10,12,12,1,+ 1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,36,36,35,35,1,1,1,1,12,12,12,1,36,31,31,1,1,36,36,31,31,31,31,31,1,1,1,34,34,34,34,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,12,36,33,34,34,31,31,31,31,31,31,30,1,31,1,1,1,1,1,1,1,1,1,1,31,31,36,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,34,35,35,36,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,1,1,1,34,35,36,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,1,1,34,35,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,0,1,1,1,0,34,35,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,36,34,34,34,34,35,35,35,33,33,+ 33,33,33,33,33,33,29,31,36,29,29,6,14,8,6,29,6,34,6,6,0,0,0,0,0,0,0,0,1,6,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,1,0,0,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,+ 2,2,2,2,2,8,8,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,34,34,35,36,36,34,34,34,34,7,7,7,0,0,0,0,16,16,30,16,16,16,16,16,16,15,29,6,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,31,31,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,1,1,1,1,34,34,33,36,34,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,10,12,7,14,14,11,7,7,7,7,0,5,36,34,36,36,34,34,34,34,35,35,34,35,36,33,33,33,33,33,34,29,29,29,29,29,29,34,29,29,0,0,30,+ 1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 29,29,29,14,31,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,8,36,34,34,35,35,35,35,34,34,33,33,+ 33,33,34,34,3,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 29,14,31,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,7,7,7,34,35,33,36,34,34,36,6,7,7,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,8,36,34,34,36,36,36,34,36,34,14,14,17,17,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,7,7,36,33,33,33,36,36,35,14,14,14,14,14,14,14,32,32,0,9,0,0,0,0,0,0,0,0,+ 1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,29,29,29,0,30,30,30,30,30,30,29,29,30,30,30,30,29,31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,29,37,37,31,29,29,2,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,39,1,0,0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,29,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,21,19,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,21,19,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,34,1,1,1,3,1,1,1,1,29,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,36,36,35,34,36,0,0,0,0,35,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,+ 31,31,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,13,36,36,36,36,36,36,36,36,36,36,36,+ 36,36,36,36,3,29,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,1,1,0,0,0,0,0,0,0,0,0,0,1,34,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,34,34,34,34,34,30,30,30,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,35,35,35,34,35,35,35,35,14,14,14,16,36,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 29,29,14,31,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,8,36,36,34,34,35,35,33,33,34,12,13,12,+ 3,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,0,0,0,0,0,0,1,1,1,1,1,34,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,29,34,34,34,35,34,33,33,34,35,13,10,11,12,0,0,0,0,0,0,0,0,0,+ 1,1,1,14,1,1,1,1,1,1,1,1,14,16,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,2,2,2,0,0,0,1,31,29,31,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,35,1,35,35,34,1,1,35,35,1,1,1,1,1,35,29,+ 1,29,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,33,35,34,33,36,0,0,0,0,0,31,6,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,36,36,34,36,36,35,36,36,0,31,35,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,35,35,35,0,34,35,0,0,0,0,0,36,30,30,29,1,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,9,9,9,0,0,0,0,6,+ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,29,29,29,8,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,34,34,34,34,34,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,34,34,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,+ 1,1,1,1,1,1,30,30,30,30,30,30,30,30,30,30,30,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,9,9,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,+ 0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 31,29,31,37,37,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,34,34,34,34,35,35,35,35,+ 35,35,34,34,34,34,3,0,0,0,0,0,0,0,0,0,0,0,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,1,1,1,1,1,1,1,1,1,1,34,1,1,34,34,1,0,0,0,0,0,0,0,0,0,40,+ 29,29,31,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,36,33,36,35,35,34,34,36,36,3,9,0,0,0,0,0,+ 0,0,35,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 29,29,29,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,35,35,35,34,34,33,35,34,34,35,34,34,6,8,0,1,1,1,1,1,1,1,1,1,1,+ 0,0,0,0,1,36,36,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,0,0,0,0,0,0,0,0,0,0,0,0,+ 29,29,31,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,36,33,36,35,35,35,35,35,35,34,34,34,34,+ 3,1,38,38,0,0,0,0,0,6,9,34,35,0,33,29,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,36,36,36,35,34,34,34,34,29,3,8,8,0,0,0,0,0,0,29,1,+ 1,35,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,1,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,29,36,33,36,35,35,34,34,34,34,9,35,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,+ 29,29,31,31,0,1,1,1,1,1,1,1,1,0,0,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,9,9,1,36,36,+ 34,36,36,36,36,0,0,33,33,0,0,33,33,3,0,0,0,0,0,0,0,0,0,36,0,0,0,0,0,0,1,1,1,1,36,36,0,0,29,29,29,29,29,29,29,0,0,0,29,29,29,29,29,0,0,0,0,0,0,0,0,0,0,0,+ 1,1,1,1,1,1,1,1,1,1,0,1,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,36,34,34,35,35,35,35,35,+ 35,0,33,0,0,33,0,33,33,36,31,0,31,31,29,9,6,38,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,29,30,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,36,33,36,35,35,35,35,35,35,34,34,+ 36,36,3,29,29,31,9,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,6,1,37,37,0,0,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,36,33,36,35,35,35,35,35,35,33,34,33,33,36,33,29,+ 29,31,3,9,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,36,33,36,35,35,35,35,0,0,33,33,33,33,29,29,31,3,+ 9,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,35,35,0,0,0,0,0,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,36,36,36,35,35,35,35,35,35,34,34,36,36,29,31,3,+ 34,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,29,31,34,33,36,35,35,34,34,34,34,3,9,1,0,0,0,0,0,0,0,+ 1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,12,3,11,36,36,34,34,35,35,33,34,35,34,34,34,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,+ 1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,36,33,36,35,35,35,35,34,34,34,34,29,31,3,9,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,1,0,0,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,36,36,36,36,36,33,0,33,33,0,0,29,29,36,6,38,+ 13,38,13,9,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,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,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,36,33,36,35,35,35,35,0,0,34,34,36,36,31,31,3,1,0,0,33,0,0,0,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,34,35,35,34,34,34,34,34,34,35,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,6,35,29,29,29,29,31,37,7,7,7,7,0,+ 0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,1,34,35,35,34,34,34,36,36,35,35,35,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,38,38,38,38,38,38,15,15,15,15,15,15,15,15,15,15,15,15,29,31,8,6,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,36,34,34,35,35,35,35,35,0,34,34,34,34,29,29,31,3,+ 1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,0,7,7,7,7,7,7,7,35,33,35,34,36,29,29,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,34,34,34,34,34,35,0,0,0,34,0,34,34,0,34,+ 29,29,9,34,35,6,38,12,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,36,36,36,36,36,0,34,34,0,36,36,29,31,6,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,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,1,1,2,34,35,33,36,0,0,0,0,0,0,0,0,0,+ 29,29,38,31,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,36,36,34,34,35,35,35,0,0,0,33,33,+ 34,36,6,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,+ 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,+ 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,+ 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,+ 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,22,22,22,22,22,22,22,19,21,22,22,22,18,18,18,18,+ 23,18,18,18,18,18,18,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,0,0,0,0,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,+ 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,+ 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,+ 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,+ 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,+ 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,+ 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,34,34,34,34,34,34,34,34,34,34,34,34,10,10,13,29,12,35,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,29,29,29,29,29,29,29,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 31,31,31,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,36,36,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,9,0,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,+ 35,35,35,35,35,35,35,35,0,0,0,0,0,0,0,30,30,30,30,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,+ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,29,29,29,29,29,29,29,1,1,1,1,1,1,1,0,0,+ 1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,29,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,29,29,29,29,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,1,1,1,34,34,34,34,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,35,35,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,8,8,8,8,8,8,8,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+};++KBTS_INLINE kbts_u8 kbts__GetUnicodeUseClass(kbts_u32 Codepoint)+{+ return (Codepoint < 1114110) ? kbts__UnicodeUseClass_Data[((kbts_un)kbts__UnicodeUseClass_PageIndices[Codepoint/256] * 256) | (Codepoint & 255)] : 0;+}++static kbts_u8 kbts__UnicodeScriptExtension_PageIndices[8703] = {+ 0,1,2,2,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,+ 30,31,32,32,33,34,35,36,37,37,37,37,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,2,2,53,54,+ 55,56,57,58,59,59,59,59,60,59,59,59,59,59,59,59,61,61,59,59,59,59,62,63,64,65,66,67,68,61,61,69,+ 70,71,72,73,74,75,76,77,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,78,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 79,79,79,79,79,79,79,79,79,80,81,81,82,83,84,85,86,87,88,89,90,91,92,93,32,32,32,32,32,32,32,32,+ 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,+ 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,+ 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,94,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,95,96,97,97,98,99,100,101,102,103,+ 104,105,106,107,61,108,109,110,111,112,113,114,115,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,+ 134,135,136,137,138,139,140,141,142,143,61,144,145,146,147,61,148,149,150,151,152,153,154,155,156,157,158,159,61,160,161,162,+ 163,163,163,163,163,163,163,164,165,163,166,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,167,+ 168,168,168,168,168,168,168,168,169,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,+ 168,168,168,168,168,168,168,170,171,171,171,171,172,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,173,61,61,61,61,61,61,61,61,61,61,61,61,61,174,174,174,174,175,176,177,178,61,61,179,61,180,181,182,183,+ 184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,+ 184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,185,184,184,184,184,184,184,186,186,186,187,188,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,189,+ 190,191,192,193,193,194,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,195,196,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,59,197,59,59,59,198,199,200,+ 59,201,202,203,204,205,206,61,207,208,209,59,59,210,59,211,212,212,212,212,212,213,61,61,61,61,61,61,61,61,214,61,+ 215,216,217,61,61,218,61,61,61,219,61,220,61,61,61,221,222,223,224,61,61,61,61,61,225,226,227,61,228,229,61,61,+ 230,231,59,232,233,61,59,59,59,59,59,59,59,234,235,236,237,238,59,59,239,240,59,241,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 242,61,243,244,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+ 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,+};++static kbts_u16 kbts__UnicodeScriptExtension_Data[31360] = {+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,929,929,929,929,929,+ 929,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,2305,929,929,929,929,929,929,929,929,929,929,929,929,16,929,929,2305,929,929,929,929,929,+ 2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,929,2305,2305,2305,2305,2305,2305,2305,2305,+ 2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,929,2305,2305,2305,2305,2305,2305,2305,2305,+ 2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,+ 2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,+ 2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,+ 2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,+ 2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,+ 2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,929,929,929,519,929,929,929,+ 929,929,929,929,929,929,929,738,929,738,738,738,929,610,929,929,929,929,929,929,929,929,929,802,929,738,929,929,929,929,929,929,+ 2305,2305,2305,2305,2305,929,929,929,929,929,417,417,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 872,1128,1380,1509,1675,2022,932,2217,2506,1442,2819,2916,3043,1538,3138,961,1538,3203,961,3300,961,961,961,961,961,961,961,961,961,961,961,961,+ 2850,961,961,3429,3588,2850,961,961,961,961,961,961,961,1539,2850,961,3715,3814,961,961,961,961,961,961,961,961,961,961,961,961,961,961,+ 961,961,1441,961,961,1441,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,1218,961,961,961,961,961,4003,961,+ 961,961,961,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,1441,1441,1441,1441,4098,4098,1441,1441,1,1,1441,1441,1441,1441,929,1441,+ 1,1,1,1,1441,929,1441,929,1441,1441,1441,1,1441,1,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,+ 1441,1441,1,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,+ 1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,+ 1441,1441,801,801,801,801,801,801,801,801,801,801,801,801,801,801,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,+ 897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,+ 897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,+ 897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,+ 897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,+ 897,897,897,4162,4226,1410,1410,4226,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,+ 897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,+ 897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,+ 897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,+ 897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,+ 897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,1,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,+ 161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,1,1,161,161,161,161,161,161,161,+ 161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,+ 161,161,161,161,161,161,161,161,161,4291,161,1,1,161,161,161,1,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,+ 1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,+ 1729,1729,1729,1729,1729,1729,1729,1729,1,1,1,1,1,1,1,1,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,+ 1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1,1,1,1,1729,1729,1729,1729,1729,1729,1,1,1,1,1,1,1,1,1,1,1,+ 129,129,129,129,129,929,129,129,129,129,129,129,4391,129,129,129,129,129,129,129,129,129,129,129,129,129,129,4391,4611,129,129,4712,+ 129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,+ 4969,129,129,129,129,129,129,129,129,129,129,4610,4610,4610,4610,4610,4610,4610,4610,4610,4610,4610,129,129,129,129,129,129,129,129,129,129,+ 5251,5251,5251,5251,5251,5251,5251,5251,5251,5251,129,129,129,129,129,129,4610,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,+ 129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,+ 129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,+ 129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,4994,129,129,129,129,129,129,129,129,929,129,129,+ 129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,+ 4577,4577,4577,4577,4577,4577,4577,4577,4577,4577,4577,4577,4577,4577,1,4577,4577,4577,4577,4577,4577,4577,4577,4577,4577,4577,4577,4577,4577,4577,4577,4577,+ 4577,4577,4577,4577,4577,4577,4577,4577,4577,4577,4577,4577,4577,4577,4577,4577,4577,4577,4577,4577,4577,4577,4577,4577,4577,4577,4577,4577,4577,4577,4577,4577,+ 4577,4577,4577,4577,4577,4577,4577,4577,4577,4577,4577,1,1,4577,4577,4577,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,+ 129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,+ 4929,4929,4929,4929,4929,4929,4929,4929,4929,4929,4929,4929,4929,4929,4929,4929,4929,4929,4929,4929,4929,4929,4929,4929,4929,4929,4929,4929,4929,4929,4929,4929,+ 4929,4929,4929,4929,4929,4929,4929,4929,4929,4929,4929,4929,4929,4929,4929,4929,4929,4929,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,+ 3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,3297,1,1,3297,3297,3297,+ 4129,4129,4129,4129,4129,4129,4129,4129,4129,4129,4129,4129,4129,4129,4129,4129,4129,4129,4129,4129,4129,4129,4129,4129,4129,4129,4129,4129,4129,4129,4129,4129,+ 4129,4129,4129,4129,4129,4129,4129,4129,4129,4129,4129,4129,4129,4129,1,1,4129,4129,4129,4129,4129,4129,4129,4129,4129,4129,4129,4129,4129,4129,4129,1,+ 2657,2657,2657,2657,2657,2657,2657,2657,2657,2657,2657,2657,2657,2657,2657,2657,2657,2657,2657,2657,2657,2657,2657,2657,2657,2657,2657,2657,1,1,2657,1,+ 4577,4577,4577,4577,4577,4577,4577,4577,4577,4577,4577,1,1,1,1,1,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,+ 129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,1,129,129,1,1,1,1,1,129,129,129,129,129,129,129,129,129,+ 129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,+ 129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,+ 129,129,929,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,5357,5772,961,961,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 1025,1025,1025,1025,6165,6839,7556,7556,7556,7556,7556,7556,7556,7556,7556,7556,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 353,353,353,353,1,353,353,353,353,353,353,353,353,1,1,353,353,1,1,353,353,353,353,353,353,353,353,353,353,353,353,353,+ 353,353,353,353,353,353,353,353,353,1,353,353,353,353,353,353,353,1,353,1,1,1,353,353,353,353,1,1,353,353,353,353,+ 353,353,353,353,353,1,1,353,353,1,1,353,353,353,353,1,1,1,1,1,1,1,1,353,1,1,1,1,353,353,1,353,+ 353,353,353,353,1,1,7683,7683,7683,7683,7683,7683,7683,7683,7683,7683,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,1,+ 1,1537,1537,1537,1,1537,1537,1537,1537,1537,1537,1,1,1,1,1537,1537,1,1,1537,1537,1537,1537,1537,1537,1537,1537,1537,1537,1537,1537,1537,+ 1537,1537,1537,1537,1537,1537,1537,1537,1537,1,1537,1537,1537,1537,1537,1537,1537,1,1537,1537,1,1537,1537,1,1537,1537,1,1,1537,1,1537,1537,+ 1537,1537,1537,1,1,1,1,1537,1537,1,1,1537,1537,1537,1,1,1,1537,1,1,1,1,1,1,1,1537,1537,1537,1537,1,1537,1,+ 1,1,1,1,1,1,7778,7778,7778,7778,7778,7778,7778,7778,7778,7778,1537,1537,1537,1537,1537,1537,1537,1,1,1,1,1,1,1,1,1,+ 1,1473,1473,1473,1,1473,1473,1473,1473,1473,1473,1473,1473,1473,1,1473,1473,1473,1,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,+ 1473,1473,1473,1473,1473,1473,1473,1473,1473,1,1473,1473,1473,1473,1473,1473,1473,1,1473,1473,1,1473,1473,1473,1473,1473,1,1,1473,1473,1473,1473,+ 1473,1473,1473,1473,1473,1473,1,1473,1473,1473,1,1473,1473,1473,1,1,1473,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1473,1473,1473,1473,1,1,7842,7842,7842,7842,7842,7842,7842,7842,7842,7842,1473,1473,1,1,1,1,1,1,1,1473,1473,1473,1473,1473,1473,1473,+ 1,3777,3777,3777,1,3777,3777,3777,3777,3777,3777,3777,3777,1,1,3777,3777,1,1,3777,3777,3777,3777,3777,3777,3777,3777,3777,3777,3777,3777,3777,+ 3777,3777,3777,3777,3777,3777,3777,3777,3777,1,3777,3777,3777,3777,3777,3777,3777,1,3777,3777,1,3777,3777,3777,3777,3777,1,1,3777,3777,3777,3777,+ 3777,3777,3777,3777,3777,1,1,3777,3777,1,1,3777,3777,3777,1,1,1,1,1,1,1,3777,3777,3777,1,1,1,1,3777,3777,1,3777,+ 3777,3777,3777,3777,1,1,3777,3777,3777,3777,3777,3777,3777,3777,3777,3777,3777,3777,3777,3777,3777,3777,3777,3777,1,1,1,1,1,1,1,1,+ 1,1,4801,4801,1,4801,4801,4801,4801,4801,4801,1,1,1,4801,4801,4801,1,4801,4801,4801,4801,1,1,1,4801,4801,1,4801,1,4801,4801,+ 1,1,1,4801,4801,1,1,1,4801,4801,4801,1,1,1,4801,4801,4801,4801,4801,4801,4801,4801,4801,4801,4801,4801,1,1,1,1,4801,4801,+ 4801,4801,4801,1,1,1,4801,4801,4801,1,4801,4801,4801,4801,1,1,4801,1,1,1,1,1,1,4801,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,7906,7906,7906,7906,7906,7906,7906,7906,7906,7906,7906,7906,7906,7906,4801,4801,4801,4801,4801,4801,4801,1,1,1,1,1,+ 4897,4897,4897,4897,4897,4897,4897,4897,4897,4897,4897,4897,4897,1,4897,4897,4897,1,4897,4897,4897,4897,4897,4897,4897,4897,4897,4897,4897,4897,4897,4897,+ 4897,4897,4897,4897,4897,4897,4897,4897,4897,1,4897,4897,4897,4897,4897,4897,4897,4897,4897,4897,4897,4897,4897,4897,4897,4897,1,1,4897,4897,4897,4897,+ 4897,4897,4897,4897,4897,1,4897,4897,4897,1,4897,4897,4897,4897,1,1,1,1,1,1,1,4897,4897,1,4897,4897,4897,1,1,4897,1,1,+ 4897,4897,4897,4897,1,1,4897,4897,4897,4897,4897,4897,4897,4897,4897,4897,1,1,1,1,1,1,1,4897,4897,4897,4897,4897,4897,4897,4897,4897,+ 1953,1953,1953,1953,1953,1953,1953,1953,1953,1953,1953,1953,1953,1,1953,1953,1953,1,1953,1953,1953,1953,1953,1953,1953,1953,1953,1953,1953,1953,1953,1953,+ 1953,1953,1953,1953,1953,1953,1953,1953,1953,1,1953,1953,1953,1953,1953,1953,1953,1953,1953,1953,1,1953,1953,1953,1953,1953,1,1,1953,1953,1953,1953,+ 1953,1953,1953,1953,1953,1,1953,1953,1953,1,1953,1953,1953,1953,1,1,1,1,1,1,1,1953,1953,1,1,1,1,1,1,1953,1953,1,+ 1953,1953,1953,1953,1,1,7971,7971,7971,7971,7971,7971,7971,7971,7971,7971,1,1953,1953,1953,1,1,1,1,1,1,1,1,1,1,1,1,+ 2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,1,2625,2625,2625,1,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,+ 2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,+ 2625,2625,2625,2625,2625,1,2625,2625,2625,1,2625,2625,2625,2625,2625,2625,1,1,1,1,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,+ 2625,2625,2625,2625,1,1,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,2625,+ 1,4353,4353,4353,1,4353,4353,4353,4353,4353,4353,4353,4353,4353,4353,4353,4353,4353,4353,4353,4353,4353,4353,1,1,1,4353,4353,4353,4353,4353,4353,+ 4353,4353,4353,4353,4353,4353,4353,4353,4353,4353,4353,4353,4353,4353,4353,4353,4353,4353,1,4353,4353,4353,4353,4353,4353,4353,4353,4353,1,4353,1,1,+ 4353,4353,4353,4353,4353,4353,4353,1,1,1,4353,1,1,1,1,4353,4353,4353,4353,4353,4353,1,4353,1,4353,4353,4353,4353,4353,4353,4353,4353,+ 1,1,1,1,1,1,4353,4353,4353,4353,4353,4353,4353,4353,4353,4353,1,1,4353,4353,4353,1,1,1,1,1,1,1,1,1,1,1,+ 1,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,+ 4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,1,1,1,1,929,+ 4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,4961,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,2273,2273,1,2273,1,2273,2273,2273,2273,2273,1,2273,2273,2273,2273,2273,2273,2273,2273,2273,2273,2273,2273,2273,2273,2273,2273,2273,2273,2273,2273,+ 2273,2273,2273,2273,1,2273,1,2273,2273,2273,2273,2273,2273,2273,2273,2273,2273,2273,2273,2273,2273,2273,2273,2273,2273,2273,2273,2273,2273,2273,1,1,+ 2273,2273,2273,2273,2273,1,2273,1,2273,2273,2273,2273,2273,2273,2273,1,2273,2273,2273,2273,2273,2273,2273,2273,2273,2273,1,1,2273,2273,2273,2273,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,+ 4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,+ 4993,4993,4993,4993,4993,4993,4993,4993,1,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,+ 4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,1,1,1,1,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,+ 4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,1,4993,4993,4993,4993,4993,4993,4993,+ 4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,1,4993,4993,+ 4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,4993,1,4993,4993,4993,4993,4993,4993,4993,929,929,929,929,4993,4993,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,+ 3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,+ 8067,8067,8067,8067,8067,8067,8067,8067,8067,8067,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,+ 3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,+ 3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,+ 1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,+ 1313,1313,1313,1313,1313,1313,1,1313,1,1,1,1,1,1313,1,1,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,+ 1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,8163,1313,1313,1313,1313,+ 1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,+ 1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,+ 1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,+ 1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,+ 1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,+ 1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,+ 1249,1249,1249,1249,1249,1249,1249,1249,1249,1,1249,1249,1249,1249,1,1,1249,1249,1249,1249,1249,1249,1249,1,1249,1,1249,1249,1249,1249,1,1,+ 1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,+ 1249,1249,1249,1249,1249,1249,1249,1249,1249,1,1249,1249,1249,1249,1,1,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,+ 1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1,1249,1249,1249,1249,1,1,1249,1249,1249,1249,1249,1249,1249,1,+ 1249,1,1249,1249,1249,1249,1,1,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1,1249,1249,1249,1249,1249,1249,1249,1249,+ 1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,+ 1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1,1249,1249,1249,1249,1,1,1249,1249,1249,1249,1249,1249,1249,1249,+ 1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,+ 1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1,1,1249,1249,1249,+ 1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1,1,1,+ 1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1,1,1,1,1,1,+ 705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,+ 705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,+ 705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,1,1,705,705,705,705,705,705,1,1,+ 545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,+ 545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,+ 545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,+ 545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,+ 3393,3393,3393,3393,3393,3393,3393,3393,3393,3393,3393,3393,3393,3393,3393,3393,3393,3393,3393,3393,3393,3393,3393,3393,3393,3393,3393,3393,3393,1,1,1,+ 4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,+ 4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,+ 4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,4097,1,1,1,1,1,1,1,+ 4609,4609,4609,4609,4609,4609,4609,4609,4609,4609,4609,4609,4609,4609,4609,4609,4609,4609,4609,4609,4609,4609,1,1,1,1,1,1,1,1,1,4609,+ 1665,1665,1665,1665,1665,1665,1665,1665,1665,1665,1665,1665,1665,1665,1665,1665,1665,1665,1665,1665,1665,8260,8260,1,1,1,1,1,1,1,1,1,+ 513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,1,1,1,1,1,1,1,1,1,1,1,1,+ 4641,4641,4641,4641,4641,4641,4641,4641,4641,4641,4641,4641,4641,1,4641,4641,4641,1,4641,4641,1,1,1,1,1,1,1,1,1,1,1,1,+ 2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,+ 2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,+ 2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,1,1,+ 2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,1,1,1,1,1,1,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,1,1,1,1,1,1,+ 3009,3009,8386,8386,3009,8386,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,1,1,1,1,1,1,+ 3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,+ 3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,+ 3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,1,1,1,1,1,1,1,+ 3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,+ 3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,1,1,1,1,1,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,+ 545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,+ 545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,1,1,1,1,1,1,1,1,1,1,+ 2369,2369,2369,2369,2369,2369,2369,2369,2369,2369,2369,2369,2369,2369,2369,2369,2369,2369,2369,2369,2369,2369,2369,2369,2369,2369,2369,2369,2369,2369,2369,1,+ 2369,2369,2369,2369,2369,2369,2369,2369,2369,2369,2369,2369,1,1,1,1,2369,2369,2369,2369,2369,2369,2369,2369,2369,2369,2369,2369,1,1,1,1,+ 2369,1,1,1,2369,2369,2369,2369,2369,2369,2369,2369,2369,2369,2369,2369,4673,4673,4673,4673,4673,4673,4673,4673,4673,4673,4673,4673,4673,4673,4673,4673,+ 4673,4673,4673,4673,4673,4673,4673,4673,4673,4673,4673,4673,4673,4673,1,1,4673,4673,4673,4673,4673,1,1,1,1,1,1,1,1,1,1,1,+ 3265,3265,3265,3265,3265,3265,3265,3265,3265,3265,3265,3265,3265,3265,3265,3265,3265,3265,3265,3265,3265,3265,3265,3265,3265,3265,3265,3265,3265,3265,3265,3265,+ 3265,3265,3265,3265,3265,3265,3265,3265,3265,3265,3265,3265,1,1,1,1,3265,3265,3265,3265,3265,3265,3265,3265,3265,3265,3265,3265,3265,3265,3265,3265,+ 3265,3265,3265,3265,3265,3265,3265,3265,3265,3265,1,1,1,1,1,1,3265,3265,3265,3265,3265,3265,3265,3265,3265,3265,3265,1,1,1,3265,3265,+ 2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,2145,+ 481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,1,1,481,481,+ 4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,+ 4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,1,+ 4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,1,1,4705,+ 4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,1,1,1,1,1,1,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,1,1,1,1,1,1,+ 4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,4705,1,1,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,+ 961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,+ 225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,+ 225,225,225,225,225,225,225,225,225,225,225,225,225,1,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,+ 225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,+ 4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,+ 4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,4481,+ 321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,+ 321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,1,1,1,1,1,1,1,1,321,321,321,321,+ 2337,2337,2337,2337,2337,2337,2337,2337,2337,2337,2337,2337,2337,2337,2337,2337,2337,2337,2337,2337,2337,2337,2337,2337,2337,2337,2337,2337,2337,2337,2337,2337,+ 2337,2337,2337,2337,2337,2337,2337,2337,2337,2337,2337,2337,2337,2337,2337,2337,2337,2337,2337,2337,2337,2337,2337,2337,1,1,1,2337,2337,2337,2337,2337,+ 2337,2337,2337,2337,2337,2337,2337,2337,2337,2337,1,1,1,2337,2337,2337,3425,3425,3425,3425,3425,3425,3425,3425,3425,3425,3425,3425,3425,3425,3425,3425,+ 3425,3425,3425,3425,3425,3425,3425,3425,3425,3425,3425,3425,3425,3425,3425,3425,3425,3425,3425,3425,3425,3425,3425,3425,3425,3425,3425,3425,3425,3425,3425,3425,+ 897,897,897,897,897,897,897,897,897,897,897,1,1,1,1,1,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,+ 1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1,1,1313,1313,1313,+ 4481,4481,4481,4481,4481,4481,4481,4481,1,1,1,1,1,1,1,1,8452,1025,8452,8483,1025,5346,5346,8578,5346,8578,8646,1025,8578,8578,1025,1025,+ 8578,5346,1025,1025,1025,1025,1025,1025,1025,8834,5346,1025,1025,5346,1025,1025,1025,1025,8907,5378,9252,5346,5346,353,5378,5378,3201,1,1,1,1,1,+ 2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,+ 2305,2305,2305,2305,2305,2305,1441,1441,1441,1441,1441,897,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,+ 2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,1441,1441,1441,+ 1441,1441,2305,2305,2305,2305,1441,1441,1441,1441,1441,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,897,2305,2305,2305,2305,2305,2305,2305,+ 2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,+ 2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,1441,+ 1441,1441,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,+ 961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,9379,961,4577,961,961,961,961,961,+ 1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1,1,1441,1441,1441,1441,1441,1441,1,1,+ 1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,+ 1441,1441,1441,1441,1441,1441,1,1,1441,1441,1441,1441,1441,1441,1,1,1441,1441,1441,1441,1441,1441,1441,1441,1,1441,1,1441,1,1441,1,1441,+ 1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1,1,+ 1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,+ 1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,+ 1441,1441,1441,1441,1441,1,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1,1,1441,1441,1441,1441,1441,1441,1,1441,1441,1441,+ 1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1,1,1441,1441,1441,1,1441,1441,1441,1441,1441,1441,1441,1441,1441,1,+ 929,929,929,929,929,929,929,929,929,929,929,929,961,961,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,9475,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,4706,929,929,929,929,929,929,929,929,929,929,9574,929,929,9764,929,929,+ 929,929,929,929,929,1,929,929,929,929,929,929,929,929,929,929,929,2305,1,1,929,929,929,929,929,929,929,929,929,929,929,2305,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,1,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,1,1,1,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,+ 961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,9891,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,1441,929,929,929,2305,2305,929,929,929,929,929,929,2305,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,2305,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,+ 2305,2305,2305,2305,2305,2305,2305,2305,2305,929,929,929,1,1,1,1,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 929,929,929,929,929,929,929,929,929,929,929,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,1,1,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,1,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,+ 1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,+ 1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,+ 2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,+ 801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,+ 801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,+ 801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,+ 801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,1,1,1,1,1,801,801,801,801,801,801,801,+ 1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,+ 1313,1313,1313,1313,1313,1313,1,1313,1,1,1,1,1,1313,1,1,5025,5025,5025,5025,5025,5025,5025,5025,5025,5025,5025,5025,5025,5025,5025,5025,+ 5025,5025,5025,5025,5025,5025,5025,5025,5025,5025,5025,5025,5025,5025,5025,5025,5025,5025,5025,5025,5025,5025,5025,5025,5025,5025,5025,5025,5025,5025,5025,5025,+ 5025,5025,5025,5025,5025,5025,5025,5025,1,1,1,1,1,1,1,5025,5025,1,1,1,1,1,1,1,1,1,1,1,1,1,1,5025,+ 1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1,1,1,1,1,1,1,1,1,+ 1249,1249,1249,1249,1249,1249,1249,1,1249,1249,1249,1249,1249,1249,1249,1,1249,1249,1249,1249,1249,1249,1249,1,1249,1249,1249,1249,1249,1249,1249,1,+ 1249,1249,1249,1249,1249,1249,1249,1,1249,1249,1249,1249,1249,1249,1249,1,1249,1249,1249,1249,1249,1249,1249,1,1249,1249,1249,1249,1249,1249,1249,1,+ 897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,9986,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,10050,10119,929,929,929,929,929,929,929,929,929,929,1121,929,929,929,+ 929,10339,929,4226,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,10434,10434,10434,10434,10434,10434,10434,10434,10434,10434,10434,10434,10434,10434,10434,10434,+ 929,10503,10728,10501,929,1,769,1,10984,10984,11241,11241,11526,11526,11526,11526,11526,11526,929,10501,11526,11526,11526,11526,11526,11526,11526,11526,10501,10501,10501,10501,+ 929,1,1,1,1,1,1,1,1,1,10498,10498,10498,10498,1601,1601,10501,10594,10594,10594,10594,10594,929,10501,1,1,1,1,11715,11715,769,769,+ 1,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,+ 1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,+ 1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1,1,10594,10594,10594,10594,1761,1761,1761,+ 10594,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,+ 1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,+ 1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,11526,10594,1985,1985,1985,+ 1,1,1,1,1,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,+ 417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,1,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,+ 1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,+ 1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,+ 1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,+ 417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,+ 769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,+ 769,769,769,769,769,769,1,1,1,1,1,1,1,1,1,10434,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,+ 1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1,+ 769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,+ 769,769,769,769,769,769,769,769,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,929,+ 769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,+ 769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 769,769,769,769,769,769,769,769,769,769,769,769,929,929,929,929,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,+ 1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,769,+ 1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,+ 1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,+ 1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,769,769,769,769,769,769,769,769,+ 769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,929,929,929,929,929,929,929,929,929,929,769,769,769,769,769,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,929,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,+ 5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,+ 5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,+ 5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,+ 5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,1,1,1,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,+ 5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,5377,+ 5377,5377,5377,5377,5377,5377,5377,1,1,1,1,1,1,1,1,1,2465,2465,2465,2465,2465,2465,2465,2465,2465,2465,2465,2465,2465,2465,2465,2465,+ 2465,2465,2465,2465,2465,2465,2465,2465,2465,2465,2465,2465,2465,2465,2465,2465,2465,2465,2465,2465,2465,2465,2465,2465,2465,2465,2465,2465,2465,2465,2465,2465,+ 5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,+ 5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,+ 5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,+ 5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,+ 5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,+ 5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,5217,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,+ 897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,4226,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,+ 897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,+ 257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,+ 257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,+ 257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,1,1,1,1,1,1,1,1,+ 11810,11810,11810,11810,11810,11810,11810,11810,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,+ 2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,+ 2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,+ 2305,2305,2305,2305,2305,2305,2305,2305,929,929,929,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,+ 2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,+ 2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,1,1,2305,2305,1,2305,1,2305,2305,2305,2305,2305,2305,2305,2305,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,+ 4545,4545,4545,4545,4545,4545,4545,4545,4545,4545,4545,4545,4545,4545,4545,4545,4545,4545,4545,4545,4545,4545,4545,4545,4545,4545,4545,4545,4545,4545,4545,4545,+ 4545,4545,4545,4545,4545,4545,4545,4545,4545,4545,4545,4545,4545,1,1,1,11888,11888,11888,12399,12399,12399,12875,12875,13228,12875,1,1,1,1,1,1,+ 3969,3969,3969,3969,3969,3969,3969,3969,3969,3969,3969,3969,3969,3969,3969,3969,3969,3969,3969,3969,3969,3969,3969,3969,3969,3969,3969,3969,3969,3969,3969,3969,+ 3969,3969,3969,3969,3969,3969,3969,3969,3969,3969,3969,3969,3969,3969,3969,3969,3969,3969,3969,3969,3969,3969,3969,3969,1,1,1,1,1,1,1,1,+ 4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,+ 4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,+ 4161,4161,4161,4161,4161,4161,1,1,1,1,1,1,1,1,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,4161,1,1,1,1,1,1,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,13603,1025,13698,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,+ 2049,2049,2049,2049,2049,2049,2049,2049,2049,2049,2049,2049,2049,2049,2049,2049,2049,2049,2049,2049,2049,2049,2049,2049,2049,2049,2049,2049,2049,2049,2049,2049,+ 2049,2049,2049,2049,2049,2049,2049,2049,2049,2049,2049,2049,2049,2049,13763,2049,4065,4065,4065,4065,4065,4065,4065,4065,4065,4065,4065,4065,4065,4065,4065,4065,+ 4065,4065,4065,4065,4065,4065,4065,4065,4065,4065,4065,4065,4065,4065,4065,4065,4065,4065,4065,4065,1,1,1,1,1,1,1,1,1,1,1,4065,+ 1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1,1,1,+ 1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,+ 1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,+ 1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1,13858,1889,1889,1889,1889,1889,1889,1889,1889,1889,1889,1,1,1,1,1889,1889,+ 3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,1,+ 673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,+ 673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,1,1,1,1,1,1,1,1,1,+ 673,673,673,673,673,673,673,673,673,673,673,673,673,673,1,1,673,673,673,673,673,673,673,673,673,673,1,1,673,673,673,673,+ 3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,+ 4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,+ 4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,4737,+ 4737,4737,4737,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4737,4737,4737,4737,4737,+ 2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,1,1,1,1,1,1,1,1,1,+ 1,1249,1249,1249,1249,1249,1249,1,1,1249,1249,1249,1249,1249,1249,1,1,1249,1249,1249,1249,1249,1249,1,1,1,1,1,1,1,1,1,+ 1249,1249,1249,1249,1249,1249,1249,1,1249,1249,1249,1249,1249,1249,1249,1,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,+ 2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,929,2305,2305,2305,2305,+ 2305,2305,2305,2305,2305,1441,2305,2305,2305,2305,929,929,1,1,1,1,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,+ 705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,+ 705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,+ 2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,+ 2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,1,1,2817,2817,2817,2817,2817,2817,2817,2817,2817,2817,1,1,1,1,1,1,+ 1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,+ 1601,1601,1601,1601,1,1,1,1,1,1,1,1,1,1,1,1,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,+ 1601,1601,1601,1601,1601,1601,1601,1,1,1,1,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,+ 1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1,1,1,1,+ 2305,2305,2305,2305,2305,2305,2305,1,1,1,1,1,1,1,1,1,1,1,1,161,161,161,161,161,1,1,1,1,1,1729,1729,1729,+ 1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,1,1729,1729,1729,1729,1729,1,1729,1,+ 1729,1729,1,1729,1729,1,1729,1729,1729,1729,1729,1729,1729,1729,1729,1729,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,+ 129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,+ 129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,+ 129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,+ 129,129,129,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,129,129,129,129,129,129,129,129,129,129,129,129,129,+ 129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,+ 129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,+ 129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,+ 129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,+ 129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,+ 129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,+ 129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,13922,13922,+ 129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,+ 129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,+ 129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,1,1,129,129,129,129,129,129,129,129,129,129,129,129,129,129,+ 129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,+ 129,129,129,129,129,129,129,129,1,1,1,1,1,1,1,129,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,129,129,5250,129,129,129,129,129,129,129,129,129,129,5250,129,129,+ 961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,929,929,929,929,929,929,929,929,929,929,1,1,1,1,1,1,+ 961,961,961,961,961,961,961,961,961,961,961,961,961,961,897,897,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,10501,10501,929,929,929,929,929,929,929,929,929,929,929,929,1,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,1,929,929,929,929,1,1,1,1,129,129,129,129,129,1,129,129,129,129,129,129,129,129,129,129,+ 129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,+ 129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,+ 129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,+ 129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,1,1,929,+ 1,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,929,929,929,929,929,+ 929,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,929,929,929,929,929,+ 929,11526,11526,11526,11526,11526,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,10594,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,+ 1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,1985,10594,10594,+ 1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1601,1,+ 1,1,1601,1601,1601,1601,1601,1601,1,1,1601,1601,1601,1601,1601,1601,1,1,1601,1601,1601,1601,1601,1601,1,1,1601,1601,1601,1,1,1,+ 929,929,929,929,929,929,929,1,929,929,929,929,929,929,929,1,1,1,1,1,1,1,1,1,1,929,929,929,929,929,1,1,+ 2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,1,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,+ 2433,2433,2433,2433,2433,2433,2433,1,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,1,2433,2433,1,2433,+ 2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,1,1,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,+ 2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,+ 2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,+ 2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,2433,1,1,1,1,1,+ 13987,13987,14082,1,1,1,1,14147,14147,14147,14147,14147,14147,14147,14147,14147,14147,14147,14147,14147,14147,14147,14147,14147,14147,14147,14147,14147,14147,14147,14147,14147,+ 14147,14147,14147,14147,14147,14147,14147,14147,14147,14147,14147,14147,14147,14147,14147,14147,14147,14147,14147,14147,1,1,1,14082,14082,14082,14082,14082,14082,14082,14082,14082,+ 1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,+ 1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,+ 1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1,929,929,929,929,929,929,929,929,929,929,929,929,929,1,1,1,+ 1441,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,961,1,1,+ 2497,2497,2497,2497,2497,2497,2497,2497,2497,2497,2497,2497,2497,2497,2497,2497,2497,2497,2497,2497,2497,2497,2497,2497,2497,2497,2497,2497,2497,1,1,1,+ 577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,+ 577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 14242,14242,14242,14242,14242,14242,14242,14242,14242,14242,14242,14242,14242,14242,14242,14242,14242,14242,14242,14242,14242,14242,14242,14242,14242,14242,14242,14242,1,1,1,1,+ 3489,3489,3489,3489,3489,3489,3489,3489,3489,3489,3489,3489,3489,3489,3489,3489,3489,3489,3489,3489,3489,3489,3489,3489,3489,3489,3489,3489,3489,3489,3489,3489,+ 3489,3489,3489,3489,1,1,1,1,1,1,1,1,1,3489,3489,3489,1377,1377,1377,1377,1377,1377,1377,1377,1377,1377,1377,1377,1377,1377,1377,1377,+ 1377,1377,1377,1377,1377,1377,1377,1377,1377,1377,1377,1,1,1,1,1,3585,3585,3585,3585,3585,3585,3585,3585,3585,3585,3585,3585,3585,3585,3585,3585,+ 3585,3585,3585,3585,3585,3585,3585,3585,3585,3585,3585,3585,3585,3585,3585,3585,3585,3585,3585,3585,3585,3585,3585,3585,3585,3585,3585,1,1,1,1,1,+ 5185,5185,5185,5185,5185,5185,5185,5185,5185,5185,5185,5185,5185,5185,5185,5185,5185,5185,5185,5185,5185,5185,5185,5185,5185,5185,5185,5185,5185,5185,1,5185,+ 3617,3617,3617,3617,3617,3617,3617,3617,3617,3617,3617,3617,3617,3617,3617,3617,3617,3617,3617,3617,3617,3617,3617,3617,3617,3617,3617,3617,3617,3617,3617,3617,+ 3617,3617,3617,3617,1,1,1,1,3617,3617,3617,3617,3617,3617,3617,3617,3617,3617,3617,3617,3617,3617,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,+ 993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,+ 993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,4225,4225,4225,4225,4225,4225,4225,4225,4225,4225,4225,4225,4225,4225,4225,4225,+ 4225,4225,4225,4225,4225,4225,4225,4225,4225,4225,4225,4225,4225,4225,4225,4225,4225,4225,4225,4225,4225,4225,4225,4225,4225,4225,4225,4225,4225,4225,4225,4225,+ 3841,3841,3841,3841,3841,3841,3841,3841,3841,3841,3841,3841,3841,3841,3841,3841,3841,3841,3841,3841,3841,3841,3841,3841,3841,3841,3841,3841,3841,3841,1,1,+ 3841,3841,3841,3841,3841,3841,3841,3841,3841,3841,1,1,1,1,1,1,3809,3809,3809,3809,3809,3809,3809,3809,3809,3809,3809,3809,3809,3809,3809,3809,+ 3809,3809,3809,3809,3809,3809,3809,3809,3809,3809,3809,3809,3809,3809,3809,3809,3809,3809,3809,3809,1,1,1,1,3809,3809,3809,3809,3809,3809,3809,3809,+ 3809,3809,3809,3809,3809,3809,3809,3809,3809,3809,3809,3809,3809,3809,3809,3809,3809,3809,3809,3809,3809,3809,3809,3809,3809,3809,3809,3809,1,1,1,1,+ 1185,1185,1185,1185,1185,1185,1185,1185,1185,1185,1185,1185,1185,1185,1185,1185,1185,1185,1185,1185,1185,1185,1185,1185,1185,1185,1185,1185,1185,1185,1185,1185,+ 1185,1185,1185,1185,1185,1185,1185,1185,1,1,1,1,1,1,1,1,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,+ 609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,+ 609,609,609,609,1,1,1,1,1,1,1,1,1,1,1,609,5249,5249,5249,5249,5249,5249,5249,5249,5249,5249,5249,1,5249,5249,5249,5249,+ 5249,5249,5249,5249,5249,5249,5249,5249,5249,5249,5249,1,5249,5249,5249,5249,5249,5249,5249,1,5249,5249,1,5249,5249,5249,5249,5249,5249,5249,5249,5249,+ 5249,5249,1,5249,5249,5249,5249,5249,5249,5249,5249,5249,5249,5249,5249,5249,5249,5249,1,5249,5249,5249,5249,5249,5249,5249,1,5249,5249,1,1,1,+ 5089,5089,5089,5089,5089,5089,5089,5089,5089,5089,5089,5089,5089,5089,5089,5089,5089,5089,5089,5089,5089,5089,5089,5089,5089,5089,5089,5089,5089,5089,5089,5089,+ 5089,5089,5089,5089,5089,5089,5089,5089,5089,5089,5089,5089,5089,5089,5089,5089,5089,5089,5089,5089,1,1,1,1,1,1,1,1,1,1,1,1,+ 2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,+ 2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,+ 2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,+ 2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,+ 2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,+ 2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,1,1,1,1,1,1,1,1,1,+ 2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,2401,1,1,1,1,1,1,1,1,1,1,+ 2401,2401,2401,2401,2401,2401,2401,2401,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 2305,2305,2305,2305,2305,2305,1,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,+ 2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,1,2305,2305,2305,2305,2305,2305,2305,2305,2305,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 833,833,833,833,833,833,1,1,833,1,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,+ 833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,1,833,833,1,1,1,833,1,1,833,+ 1793,1793,1793,1793,1793,1793,1793,1793,1793,1793,1793,1793,1793,1793,1793,1793,1793,1793,1793,1793,1793,1793,1,1793,1793,1793,1793,1793,1793,1793,1793,1793,+ 3905,3905,3905,3905,3905,3905,3905,3905,3905,3905,3905,3905,3905,3905,3905,3905,3905,3905,3905,3905,3905,3905,3905,3905,3905,3905,3905,3905,3905,3905,3905,3905,+ 3137,3137,3137,3137,3137,3137,3137,3137,3137,3137,3137,3137,3137,3137,3137,3137,3137,3137,3137,3137,3137,3137,3137,3137,3137,3137,3137,3137,3137,3137,3137,1,+ 1,1,1,1,1,1,1,3137,3137,3137,3137,3137,3137,3137,3137,3137,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1697,1697,1697,1697,1697,1697,1697,1697,1697,1697,1697,1697,1697,1697,1697,1697,1697,1697,1697,1,1697,1697,1,1,1,1,1,1697,1697,1697,1697,1697,+ 4001,4001,4001,4001,4001,4001,4001,4001,4001,4001,4001,4001,4001,4001,4001,4001,4001,4001,4001,4001,4001,4001,4001,4001,4001,4001,4001,4001,1,1,1,4001,+ 2529,2529,2529,2529,2529,2529,2529,2529,2529,2529,2529,2529,2529,2529,2529,2529,2529,2529,2529,2529,2529,2529,2529,2529,2529,2529,1,1,1,1,1,2529,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 2913,2913,2913,2913,2913,2913,2913,2913,2913,2913,2913,2913,2913,2913,2913,2913,2913,2913,2913,2913,2913,2913,2913,2913,2913,2913,2913,2913,2913,2913,2913,2913,+ 2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,1,1,1,1,2881,2881,2881,2881,+ 2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,1,1,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,+ 2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,2881,+ 2081,2081,2081,2081,1,2081,2081,1,1,1,1,1,2081,2081,2081,2081,2081,2081,2081,2081,1,2081,2081,2081,1,2081,2081,2081,2081,2081,2081,2081,+ 2081,2081,2081,2081,2081,2081,2081,2081,2081,2081,2081,2081,2081,2081,2081,2081,2081,2081,2081,2081,2081,2081,1,1,2081,2081,2081,1,1,1,1,2081,+ 2081,2081,2081,2081,2081,2081,2081,2081,2081,1,1,1,1,1,1,1,2081,2081,2081,2081,2081,2081,2081,2081,2081,1,1,1,1,1,1,1,+ 3681,3681,3681,3681,3681,3681,3681,3681,3681,3681,3681,3681,3681,3681,3681,3681,3681,3681,3681,3681,3681,3681,3681,3681,3681,3681,3681,3681,3681,3681,3681,3681,+ 3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 2689,2689,2689,2689,2689,2689,2689,2689,2689,2689,2689,2689,2689,2689,2689,2689,2689,2689,2689,2689,2689,2689,2689,2689,2689,2689,2689,2689,2689,2689,2689,2689,+ 2689,2689,2689,2689,2689,2689,2689,1,1,1,1,2689,2689,2689,2689,2689,2689,2689,5090,2689,2689,2689,2689,1,1,1,1,1,1,1,1,1,+ 193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,+ 193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,1,1,1,193,193,193,193,193,193,193,+ 1857,1857,1857,1857,1857,1857,1857,1857,1857,1857,1857,1857,1857,1857,1857,1857,1857,1857,1857,1857,1857,1857,1,1,1857,1857,1857,1857,1857,1857,1857,1857,+ 1825,1825,1825,1825,1825,1825,1825,1825,1825,1825,1825,1825,1825,1825,1825,1825,1825,1825,1825,1,1,1,1,1,1825,1825,1825,1825,1825,1825,1825,1825,+ 4033,4033,4033,4033,4033,4033,4033,4033,4033,4033,4033,4033,4033,4033,4033,4033,4033,4033,1,1,1,1,1,1,1,4033,4033,4033,4033,1,1,1,+ 1,1,1,1,1,1,1,1,1,4033,4033,4033,4033,4033,4033,4033,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,+ 3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,3713,+ 3713,3713,3713,3713,3713,3713,3713,3713,3713,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,+ 3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,+ 3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,3521,1,1,1,1,1,1,1,3521,3521,3521,3521,3521,3521,+ 1633,1633,1633,1633,1633,1633,1633,1633,1633,1633,1633,1633,1633,1633,1633,1633,1633,1633,1633,1633,1633,1633,1633,1633,1633,1633,1633,1633,1633,1633,1633,1633,+ 1633,1633,1633,1633,1633,1633,1633,1633,1,1,1,1,1,1,1,1,1633,1633,1633,1633,1633,1633,1633,1633,1633,1633,1,1,1,1,1,1,+ 1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,+ 1281,1281,1281,1281,1281,1281,1,1,1,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,+ 1281,1281,1281,1281,1281,1281,1,1,1,1,1,1,1,1,1281,1281,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,1,+ 5345,5345,5345,5345,5345,5345,5345,5345,5345,5345,5345,5345,5345,5345,5345,5345,5345,5345,5345,5345,5345,5345,5345,5345,5345,5345,5345,5345,5345,5345,5345,5345,+ 5345,5345,5345,5345,5345,5345,5345,5345,5345,5345,1,5345,5345,5345,1,1,5345,5345,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,129,129,129,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,129,129,129,129,+ 3649,3649,3649,3649,3649,3649,3649,3649,3649,3649,3649,3649,3649,3649,3649,3649,3649,3649,3649,3649,3649,3649,3649,3649,3649,3649,3649,3649,3649,3649,3649,3649,+ 3649,3649,3649,3649,3649,3649,3649,3649,1,1,1,1,1,1,1,1,4321,4321,4321,4321,4321,4321,4321,4321,4321,4321,4321,4321,4321,4321,4321,4321,+ 4321,4321,4321,4321,4321,4321,4321,4321,4321,4321,4321,4321,4321,4321,4321,4321,4321,4321,4321,4321,4321,4321,4321,4321,4321,4321,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3745,3745,3745,3745,3745,3745,3745,3745,3745,3745,3745,3745,3745,3745,3745,3745,+ 3745,3745,3745,3745,3745,3745,3745,3745,3745,3745,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,+ 737,737,737,737,737,737,737,737,737,737,737,737,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1217,1217,1217,1217,1217,1217,1217,1217,1217,1217,1217,1217,1217,1217,1217,1217,1217,1217,1217,1217,1217,1217,1217,1,1,1,1,1,1,1,1,1,+ 449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,+ 449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,+ 449,449,449,449,449,449,449,449,449,449,449,449,449,449,1,1,1,1,449,449,449,449,449,449,449,449,449,449,449,449,449,449,+ 449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,1,1,1,1,1,1,1,1,1,449,+ 1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,+ 1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,1921,+ 1921,1921,1921,1,1,1,1,1,1,1,1,1,1,1921,1,1,4385,4385,4385,4385,4385,4385,4385,4385,4385,4385,4385,4385,4385,4385,4385,4385,+ 4385,4385,4385,4385,4385,4385,4385,4385,4385,1,1,1,1,1,1,1,4385,4385,4385,4385,4385,4385,4385,4385,4385,4385,1,1,1,1,1,1,+ 641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,+ 641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,1,641,641,641,641,641,641,641,641,641,641,+ 641,641,641,641,641,641,641,641,1,1,1,1,1,1,1,1,2561,2561,2561,2561,2561,2561,2561,2561,2561,2561,2561,2561,2561,2561,2561,2561,+ 2561,2561,2561,2561,2561,2561,2561,2561,2561,2561,2561,2561,2561,2561,2561,2561,2561,2561,2561,2561,2561,2561,2561,1,1,1,1,1,1,1,1,1,+ 4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,+ 4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,+ 4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,4193,+ 1,4353,4353,4353,4353,4353,4353,4353,4353,4353,4353,4353,4353,4353,4353,4353,4353,4353,4353,4353,4353,1,1,1,1,1,1,1,1,1,1,1,+ 2177,2177,2177,2177,2177,2177,2177,2177,2177,2177,2177,2177,2177,2177,2177,2177,2177,2177,1,2177,2177,2177,2177,2177,2177,2177,2177,2177,2177,2177,2177,2177,+ 2177,2177,2177,2177,2177,2177,2177,2177,2177,2177,2177,2177,2177,2177,2177,2177,2177,2177,2177,2177,2177,2177,2177,2177,2177,2177,2177,2177,2177,2177,2177,2177,+ 2177,2177,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 3073,3073,3073,3073,3073,3073,3073,1,3073,1,3073,3073,3073,3073,1,3073,3073,3073,3073,3073,3073,3073,3073,3073,3073,3073,3073,3073,3073,3073,1,3073,+ 3073,3073,3073,3073,3073,3073,3073,3073,3073,3073,1,1,1,1,1,1,2209,2209,2209,2209,2209,2209,2209,2209,2209,2209,2209,2209,2209,2209,2209,2209,+ 2209,2209,2209,2209,2209,2209,2209,2209,2209,2209,2209,2209,2209,2209,2209,2209,2209,2209,2209,2209,2209,2209,2209,2209,2209,2209,2209,2209,2209,2209,2209,2209,+ 2209,2209,2209,2209,2209,2209,2209,2209,2209,2209,2209,1,1,1,1,1,2209,2209,2209,2209,2209,2209,2209,2209,2209,2209,1,1,1,1,1,1,+ 1409,7906,1409,7906,1,1409,1409,1409,1409,1409,1409,1409,1409,1,1,1409,1409,1,1,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,+ 1409,1409,1409,1409,1409,1409,1409,1409,1409,1,1409,1409,1409,1409,1409,1409,1409,1,1409,1409,1,1409,1409,1409,1409,1409,1,7906,7906,1409,1409,1409,+ 1409,1409,1409,1409,1409,1,1,1409,1409,1,1,1409,1409,1409,1,1,1409,1,1,1,1,1,1,1409,1,1,1,1,1,1409,1409,1409,+ 1409,1409,1409,1409,1,1,1409,1409,1409,1409,1409,1409,1409,1,1,1,1409,1409,1409,1409,1409,1,1,1,1,1,1,1,1,1,1,1,+ 5153,5153,5153,5153,5153,5153,5153,5153,5153,5153,1,5153,1,1,5153,1,5153,5153,5153,5153,5153,5153,5153,5153,5153,5153,5153,5153,5153,5153,5153,5153,+ 5153,5153,5153,5153,5153,5153,5153,5153,5153,5153,5153,5153,5153,5153,5153,5153,5153,5153,5153,5153,5153,5153,1,5153,5153,5153,5153,5153,5153,5153,5153,5153,+ 5153,1,5153,1,1,5153,1,5153,5153,5153,5153,1,5153,5153,5153,5153,5153,5153,5153,5153,5153,5153,1,5153,5153,1,1,1,1,1,1,1,+ 1,5153,5153,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,+ 3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,+ 3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,3233,1,3233,3233,3233,+ 3233,3233,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,+ 5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,+ 5057,5057,5057,5057,5057,5057,5057,5057,1,1,1,1,1,1,1,1,5057,5057,5057,5057,5057,5057,5057,5057,5057,5057,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,+ 4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,1,1,4257,4257,4257,4257,4257,4257,4257,4257,+ 4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,4257,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,+ 2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,+ 2977,2977,2977,2977,2977,1,1,1,1,1,1,1,1,1,1,1,2977,2977,2977,2977,2977,2977,2977,2977,2977,2977,1,1,1,1,1,1,+ 3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,3009,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,+ 4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,1,1,1,1,1,1,+ 4769,4769,4769,4769,4769,4769,4769,4769,4769,4769,1,1,1,1,1,1,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,3105,+ 3105,3105,3105,3105,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,1,1,65,65,65,+ 65,65,65,65,65,65,65,65,65,65,65,65,1,1,1,1,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,+ 65,65,65,65,65,65,65,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,+ 1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,+ 5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,+ 5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,5313,1,1,1,1,1,1,1,1,1,1,1,1,5313,+ 1057,1057,1057,1057,1057,1057,1057,1,1,1057,1,1,1057,1057,1057,1057,1057,1057,1057,1057,1,1057,1057,1,1057,1057,1057,1057,1057,1057,1057,1057,+ 1057,1057,1057,1057,1057,1057,1057,1057,1057,1057,1057,1057,1057,1057,1057,1057,1057,1057,1057,1057,1057,1057,1,1057,1057,1,1,1057,1057,1057,1057,1057,+ 1057,1057,1057,1057,1057,1057,1057,1,1,1,1,1,1,1,1,1,1057,1057,1057,1057,1057,1057,1057,1057,1057,1057,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 3201,3201,3201,3201,3201,3201,3201,3201,1,1,3201,3201,3201,3201,3201,3201,3201,3201,3201,3201,3201,3201,3201,3201,3201,3201,3201,3201,3201,3201,3201,3201,+ 3201,3201,3201,3201,3201,3201,3201,3201,3201,3201,3201,3201,3201,3201,3201,3201,3201,3201,3201,3201,3201,3201,3201,3201,1,1,3201,3201,3201,3201,3201,3201,+ 3201,3201,3201,3201,3201,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,+ 5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,5409,+ 5409,5409,5409,5409,5409,5409,5409,5409,1,1,1,1,1,1,1,1,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,+ 4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,+ 4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,4417,+ 4417,4417,4417,1,1,1,1,1,1,1,1,1,1,1,1,1,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,+ 3937,3937,3937,3937,3937,3937,3937,3937,3937,3937,3937,3937,3937,3937,3937,3937,3937,3937,3937,3937,3937,3937,3937,3937,3937,3937,3937,3937,3937,3937,3937,3937,+ 3937,3937,3937,3937,3937,3937,3937,3937,3937,3937,3937,3937,3937,3937,3937,3937,3937,3937,3937,3937,3937,3937,3937,3937,3937,1,1,1,1,1,1,1,+ 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 4513,4513,4513,4513,4513,4513,4513,4513,4513,4513,4513,4513,4513,4513,4513,4513,4513,4513,4513,4513,4513,4513,4513,4513,4513,4513,4513,4513,4513,4513,4513,4513,+ 4513,4513,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4513,4513,4513,4513,4513,4513,4513,4513,4513,4513,1,1,1,1,1,1,+ 385,385,385,385,385,385,385,385,385,1,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,+ 385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,1,385,385,385,385,385,385,385,385,+ 385,385,385,385,385,385,1,1,1,1,1,1,1,1,1,1,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,+ 385,385,385,385,385,385,385,385,385,385,385,385,385,1,1,1,2721,2721,2721,2721,2721,2721,2721,2721,2721,2721,2721,2721,2721,2721,2721,2721,+ 2721,2721,2721,2721,2721,2721,2721,2721,2721,2721,2721,2721,2721,2721,2721,2721,1,1,2721,2721,2721,2721,2721,2721,2721,2721,2721,2721,2721,2721,2721,2721,+ 2721,2721,2721,2721,2721,2721,2721,2721,1,2721,2721,2721,2721,2721,2721,2721,2721,2721,2721,2721,2721,2721,2721,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 2753,2753,2753,2753,2753,2753,2753,1,2753,2753,1,2753,2753,2753,2753,2753,2753,2753,2753,2753,2753,2753,2753,2753,2753,2753,2753,2753,2753,2753,2753,2753,+ 2753,2753,2753,2753,2753,2753,2753,2753,2753,2753,2753,2753,2753,2753,2753,2753,2753,2753,2753,2753,2753,2753,2753,1,1,1,2753,1,2753,2753,1,2753,+ 2753,2753,2753,2753,2753,2753,2753,2753,1,1,1,1,1,1,1,1,2753,2753,2753,2753,2753,2753,2753,2753,2753,2753,1,1,1,1,1,1,+ 1505,1505,1505,1505,1505,1505,1,1505,1505,1,1505,1505,1505,1505,1505,1505,1505,1505,1505,1505,1505,1505,1505,1505,1505,1505,1505,1505,1505,1505,1505,1505,+ 1505,1505,1505,1505,1505,1505,1505,1505,1505,1505,1505,1505,1505,1505,1505,1,1505,1505,1,1505,1505,1505,1505,1505,1505,1,1,1,1,1,1,1,+ 1505,1505,1505,1505,1505,1505,1505,1505,1505,1505,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 2593,2593,2593,2593,2593,2593,2593,2593,2593,2593,2593,2593,2593,2593,2593,2593,2593,2593,2593,2593,2593,2593,2593,2593,2593,1,1,1,1,1,1,1,+ 2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,1,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,+ 2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,1,1,1,2017,2017,+ 2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,2017,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2465,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 4801,4801,4801,4801,4801,4801,4801,4801,4801,4801,4801,4801,4801,4801,4801,4801,7906,7906,4801,7906,4801,4801,4801,4801,4801,4801,4801,4801,4801,4801,4801,4801,+ 4801,4801,4801,4801,4801,4801,4801,4801,4801,4801,4801,4801,4801,4801,4801,4801,4801,4801,1,1,1,1,1,1,1,1,1,1,1,1,1,4801,+ 4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,+ 4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,+ 4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,+ 4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,+ 4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,+ 4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,+ 4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,+ 4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,1,4449,4449,4449,4449,4449,1,1,1,1,1,1,1,1,1,1,1,+ 4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,+ 4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,4449,+ 4449,4449,4449,4449,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,+ 865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,+ 865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,+ 865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,+ 1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,+ 1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,+ 1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,+ 1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,+ 1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,+ 1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1,1,1,1,1,1,1,1,1,1,+ 1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,+ 1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,+ 1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,+ 1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,+ 1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1153,1,1,1,1,1,+ 97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,+ 97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,+ 97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,+ 97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,+ 97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,+ 97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,+ 97,97,97,97,97,97,97,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1569,1569,1569,1569,1569,1569,1569,1569,1569,1569,1569,1569,1569,1569,1569,1569,1569,1569,1569,1569,1569,1569,1569,1569,1569,1569,1569,1569,1569,1569,1569,1569,+ 1569,1569,1569,1569,1569,1569,1569,1569,1569,1569,1569,1569,1569,1569,1569,1569,1569,1569,1569,1569,1569,1569,1569,1569,1569,1569,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,+ 257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,+ 257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,+ 257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,+ 257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,+ 257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,1,1,1,1,1,1,1,+ 3041,3041,3041,3041,3041,3041,3041,3041,3041,3041,3041,3041,3041,3041,3041,3041,3041,3041,3041,3041,3041,3041,3041,3041,3041,3041,3041,3041,3041,3041,3041,1,+ 3041,3041,3041,3041,3041,3041,3041,3041,3041,3041,1,1,1,1,3041,3041,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,+ 4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,+ 4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,1,+ 4833,4833,4833,4833,4833,4833,4833,4833,4833,4833,1,1,1,1,1,1,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,+ 289,289,289,289,289,289,289,289,289,289,289,289,289,289,1,1,289,289,289,289,289,289,1,1,1,1,1,1,1,1,1,1,+ 3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,+ 3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,+ 3873,3873,3873,3873,3873,3873,1,1,1,1,1,1,1,1,1,1,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,1,3873,3873,3873,3873,3873,+ 3873,3873,1,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,1,1,1,1,1,3873,3873,3873,+ 3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,3873,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 2241,2241,2241,2241,2241,2241,2241,2241,2241,2241,2241,2241,2241,2241,2241,2241,2241,2241,2241,2241,2241,2241,2241,2241,2241,2241,2241,2241,2241,2241,2241,2241,+ 2241,2241,2241,2241,2241,2241,2241,2241,2241,2241,2241,2241,2241,2241,2241,2241,2241,2241,2241,2241,2241,2241,2241,2241,2241,2241,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,+ 2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,+ 2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,2785,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,+ 2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,+ 2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,1,1,1,1,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,+ 2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,+ 2945,2945,2945,2945,2945,2945,2945,2945,1,1,1,1,1,1,1,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,2945,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 4865,3329,1,1,2113,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,+ 4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,+ 4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,+ 4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,+ 4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,+ 4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,+ 4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,+ 4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,4865,1,1,1,1,1,1,1,1,+ 2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,+ 2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,+ 2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,+ 2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,+ 2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,+ 2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,+ 2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,2113,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2113,+ 4865,4865,4865,4865,4865,4865,4865,4865,4865,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1985,1985,1985,1985,1,1985,1985,1985,1985,1985,1985,1985,1,1985,1985,1,+ 1985,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,+ 1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,+ 1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,+ 1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,+ 1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,+ 1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,+ 1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,+ 1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,+ 1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,1761,+ 1985,1985,1985,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1761,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1761,1761,1761,1,1,1985,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1985,1985,1985,1985,1,1,1,1,1,1,1,1,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,+ 3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,+ 3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,+ 3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,+ 3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,+ 3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,+ 3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,+ 3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,+ 3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,3329,1,1,1,1,+ 1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,+ 1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,+ 1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,+ 1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1,1,1,1,1,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1,1,1,+ 1121,1121,1121,1121,1121,1121,1121,1121,1121,1,1,1,1,1,1,1,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1,1,1121,1121,1121,1121,+ 1121,1121,1121,1121,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,1,1,1,1,1,1,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,+ 961,961,961,961,961,961,961,961,961,961,961,961,961,961,1,1,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,+ 961,961,961,961,961,961,961,1,1,1,1,1,1,1,1,1,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,1,1,1,1,1,1,1,1,1,1,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,1,1,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,961,961,961,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,961,961,961,961,961,+ 961,961,961,929,929,961,961,961,961,961,961,961,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,961,961,961,961,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,+ 1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,1441,+ 1441,1441,1441,1441,1441,1441,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,1,1,1,1,1,1,1,1,1,1,1,1,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,1,1,1,1,1,1,1,1,1,1,1,1,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,1,1,1,1,1,1,1,1,1,+ 769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,929,929,929,929,929,929,929,1,1,1,1,1,1,1,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,1,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,1,929,929,+ 1,1,929,1,1,929,929,1,1,929,929,929,929,1,929,929,929,929,929,929,929,929,929,929,929,929,1,929,1,929,929,929,+ 929,929,929,929,1,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,1,929,929,929,929,1,1,929,929,929,929,929,929,929,929,1,929,929,929,929,929,929,929,1,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,1,929,929,929,929,1,+ 929,929,929,929,929,1,929,1,1,1,929,929,929,929,929,929,929,1,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,1,1,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,1,1,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,+ 4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,+ 4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,+ 4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,+ 4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4289,4289,4289,4289,4289,+ 1,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,4289,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,2305,1,+ 1,1,1,1,1,2305,2305,2305,2305,2305,2305,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1345,1345,1345,1345,1345,1345,1345,1,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1,1,1345,1345,1345,1345,1345,+ 1345,1345,1,1345,1345,1,1345,1345,1345,1345,1345,1,1,1,1,1,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,+ 897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,897,+ 897,897,897,897,897,897,897,897,897,897,897,897,897,897,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,897,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 3361,3361,3361,3361,3361,3361,3361,3361,3361,3361,3361,3361,3361,3361,3361,3361,3361,3361,3361,3361,3361,3361,3361,3361,3361,3361,3361,3361,3361,3361,3361,3361,+ 3361,3361,3361,3361,3361,3361,3361,3361,3361,3361,3361,3361,3361,1,1,1,3361,3361,3361,3361,3361,3361,3361,3361,3361,3361,3361,3361,3361,3361,1,1,+ 3361,3361,3361,3361,3361,3361,3361,3361,3361,3361,1,1,1,1,3361,3361,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,5121,5121,5121,5121,5121,5121,5121,5121,5121,5121,5121,5121,5121,5121,5121,5121,+ 5121,5121,5121,5121,5121,5121,5121,5121,5121,5121,5121,5121,5121,5121,5121,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 5281,5281,5281,5281,5281,5281,5281,5281,5281,5281,5281,5281,5281,5281,5281,5281,5281,5281,5281,5281,5281,5281,5281,5281,5281,5281,5281,5281,5281,5281,5281,5281,+ 5281,5281,5281,5281,5281,5281,5281,5281,5281,5281,5281,5281,5281,5281,5281,5281,5281,5281,5281,5281,5281,5281,5281,5281,5281,5281,1,1,1,1,1,5281,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3169,3169,3169,3169,3169,3169,3169,3169,3169,3169,3169,3169,3169,3169,3169,3169,+ 3169,3169,3169,3169,3169,3169,3169,3169,3169,3169,3169,3169,3169,3169,3169,3169,3169,3169,3169,3169,3169,3169,3169,3169,3169,3169,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3457,3457,3457,3457,3457,3457,3457,3457,3457,3457,3457,3457,3457,3457,3457,3457,+ 3457,3457,3457,3457,3457,3457,3457,3457,3457,3457,3457,3457,3457,3457,3457,3457,3457,3457,3457,3457,3457,3457,3457,3457,3457,3457,3457,1,1,1,1,3457,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1249,1249,1249,1249,1249,1249,1249,1,1249,1249,1249,1249,1,1249,1249,1,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1,+ 2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,+ 2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,+ 2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,+ 2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,+ 2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,+ 2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,+ 2849,2849,2849,2849,2849,1,1,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,2849,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,+ 33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,+ 33,33,33,33,33,33,33,33,33,33,33,33,1,1,1,1,33,33,33,33,33,33,33,33,33,33,1,1,1,1,33,33,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 129,129,129,129,1,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,+ 1,129,129,1,129,1,1,129,1,129,129,129,129,129,129,129,129,129,129,1,129,129,129,129,1,129,1,129,1,1,1,1,+ 1,1,129,1,1,1,1,129,1,129,1,129,1,129,129,129,1,129,129,1,129,1,1,129,1,129,1,129,1,129,1,129,+ 1,129,129,1,129,1,1,129,129,129,129,1,129,129,129,129,129,129,129,1,129,129,129,129,1,129,129,129,129,1,129,1,+ 129,129,129,129,129,129,129,129,129,129,1,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,1,1,1,1,+ 1,129,129,129,1,129,129,129,129,129,1,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,129,129,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,1,1,1,1,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,1,1,1,1,1,1,1,1,1,1,1,1,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,1,1,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 1,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,1,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,1,1,1,1,1,1,1,1,1,1,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 1761,929,929,1,1,1,1,1,1,1,1,1,1,1,1,1,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,1,1,1,1,+ 929,929,929,929,929,929,929,929,929,1,1,1,1,1,1,1,769,769,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 929,929,929,929,929,929,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,1,1,1,1,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,1,1,1,929,929,929,929,929,929,929,929,929,929,929,929,929,1,1,1,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,1,1,1,1,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,1,1,1,1,1,1,+ 929,929,929,929,929,929,929,929,929,929,929,929,1,1,1,1,929,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 929,929,929,929,929,929,929,929,929,929,929,929,1,1,1,1,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,1,1,1,1,1,1,1,1,929,929,929,929,929,929,929,929,929,929,1,1,1,1,1,1,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,1,1,1,1,1,1,1,1,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,1,1,929,929,929,929,929,929,929,929,929,929,929,929,1,1,1,1,+ 929,929,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,1,1,1,1,1,1,1,1,1,1,1,1,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,1,1,929,929,929,929,929,929,929,929,929,929,929,929,929,1,1,1,+ 929,929,929,929,929,929,929,929,929,929,1,1,1,1,1,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,1,1,1,1,1,1,1,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,1,1,929,+ 929,929,929,929,929,929,929,929,929,929,1,1,1,1,1,1,929,929,929,929,929,929,929,929,929,1,1,1,1,1,1,1,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,1,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,1,1,1,1,1,1,+ 1,929,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+ 961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,+ 961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,+ 961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,+ 961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,+ 961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,+ 961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,+ 961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,+ 961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+};++KBTS_INLINE kbts_u16 kbts__GetUnicodeScriptExtension(kbts_u32 Codepoint)+{+ return (Codepoint < 1114110) ? kbts__UnicodeScriptExtension_Data[((kbts_un)kbts__UnicodeScriptExtension_PageIndices[Codepoint/128] * 128) | (Codepoint & 127)] : 0;+}++static kbts_u8 kbts__UnicodeMirrorCodepoint_PageIndices[8703] = {+ 0,1,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,3,2,+ 2,2,2,2,2,2,2,2,2,2,2,2,2,4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,+ 5,6,2,2,7,8,9,2,2,2,2,2,2,2,10,11,2,2,2,12,13,14,2,15,2,2,2,2,16,2,2,2,+ 17,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,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,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,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,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,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,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,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,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,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,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,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,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,18,2,19,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,2,2,+};++static kbts_u32 kbts__UnicodeMirrorCodepoint_Data[2560] = {+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,41,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,62,0,60,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,93,0,91,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,125,0,123,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,187,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,171,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3899,3898,3901,3900,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5788,5787,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8250,8249,0,0,0,0,0,+ 0,0,0,0,0,8262,8261,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8318,8317,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,8334,8333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,8715,8716,8717,8712,8713,8714,0,0,0,0,0,0,0,10741,0,0,0,0,0,0,0,0,0,11262,+ 10659,10651,10656,0,10990,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8765,8764,0,0,+ 0,0,0,8909,0,8780,0,0,0,0,0,0,8773,0,0,0,0,0,8787,8786,8789,8788,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,8805,8804,8807,8806,8809,8808,8811,8810,0,0,8815,8814,8817,8816,8819,8818,8821,8820,8823,8822,8825,8824,8827,8826,8829,8828,8831,8830,+ 8833,8832,8835,8834,8837,8836,8839,8838,8841,8840,8843,8842,0,0,0,8848,8847,8850,8849,0,0,0,0,0,10680,0,0,0,0,0,0,0,+ 0,0,8867,8866,0,0,10974,0,10980,10979,0,10981,0,0,0,0,8881,8880,8883,8882,8885,8884,8887,8886,10204,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,8906,8905,8908,8907,8771,0,0,8913,8912,0,0,0,0,8919,8918,8921,8920,8923,8922,8925,8924,8927,8926,+ 8929,8928,8931,8930,8933,8932,8935,8934,8937,8936,8939,8938,8941,8940,0,0,8945,8944,8954,8955,8956,0,8957,8958,0,0,8946,8947,8948,8950,8951,0,+ 0,0,0,0,0,0,0,0,8969,8968,8971,8970,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,9002,9001,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,10089,10088,10091,10090,10093,10092,10095,10094,10097,10096,10099,10098,10101,10100,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,10180,10179,10182,10181,0,10185,10184,0,10189,0,10187,0,0,0,0,0,0,0,10198,10197,0,0,0,0,0,8888,10206,10205,0,+ 0,0,10211,10210,10213,10212,10215,10214,10217,10216,10219,10218,10221,10220,10223,10222,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,10628,10627,10630,10629,10632,10631,10634,10633,10636,10635,10640,10639,10638,10637,10642,10641,10644,10643,10646,10645,10648,10647,0,0,8737,0,0,0,0,+ 8738,0,0,8736,10661,10660,0,0,10665,10664,10667,10666,10669,10668,10671,10670,0,0,0,0,0,0,0,0,8856,0,0,0,0,0,0,0,+ 10689,10688,0,0,10693,10692,0,0,0,0,0,0,0,0,0,10704,10703,10706,10705,0,10709,10708,0,0,10713,10712,10715,10714,0,0,0,0,+ 0,0,0,0,0,0,0,0,10729,10728,0,0,0,0,0,0,0,0,0,0,0,8725,0,0,10745,10744,0,0,10749,10748,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,10796,10795,10798,10797,0,0,0,0,0,10805,10804,0,0,0,0,0,0,10813,10812,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,10853,10852,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10874,10873,10876,10875,10878,10877,10880,+ 10879,10882,10881,10884,10883,10886,10885,10888,10887,10890,10889,10892,10891,10894,10893,10896,10895,10898,10897,10900,10899,10902,10901,10904,10903,10906,10905,10908,10907,10910,10909,10912,+ 10911,10914,10913,0,0,0,10919,10918,10921,10920,10923,10922,10925,10924,0,10928,10927,10930,10929,10932,10931,10934,10933,10936,10935,10938,10937,10940,10939,10942,10941,10944,+ 10943,10946,10945,10948,10947,10950,10949,10952,10951,10954,10953,10956,10955,10958,10957,10960,10959,10962,10961,10964,10963,10966,10965,0,0,0,0,0,0,0,8870,0,+ 0,0,0,8873,8872,8875,0,0,0,0,0,0,10989,10988,8740,0,0,0,0,0,0,0,0,11000,10999,11002,11001,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8735,0,+ 0,0,11779,11778,11781,11780,0,0,0,11786,11785,0,11789,11788,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11805,11804,0,0,+ 11809,11808,11811,11810,11813,11812,11815,11814,11817,11816,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11862,11861,11864,11863,11866,11865,11868,11867,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,12297,12296,12299,12298,12301,12300,12303,12302,12305,12304,0,0,12309,12308,12311,12310,12313,12312,12315,12314,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65114,65113,65116,65115,65118,65117,0,+ 0,0,0,0,65125,65124,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+ 0,0,0,0,0,0,0,0,65289,65288,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65310,0,65308,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65341,0,65339,0,0,+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65373,0,65371,0,65376,+ 65375,0,65379,65378,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,+};++KBTS_INLINE kbts_u32 kbts__GetUnicodeMirrorCodepoint(kbts_u32 Codepoint)+{+ return (Codepoint < 1114110) ? kbts__UnicodeMirrorCodepoint_Data[((kbts_un)kbts__UnicodeMirrorCodepoint_PageIndices[Codepoint/128] * 128) | (Codepoint & 127)] : 0;+}++KBTS_INLINE kbts_u32 kbts__GetDecompositionSize(kbts_u64 Decomposition)+{+ return Decomposition & 3;+}++KBTS_INLINE kbts_u32 kbts__GetDecompositionCodepoint(kbts_u64 Decomposition, kbts_un Index){+ return (Decomposition >> (Index ? 23 : 2)) & 0x1FFFFF;+}++#define KBTS_UNICODE_DECOMPOSITION_DO_NOT_RECURSE0 (1ull << 44)+#define KBTS_UNICODE_DECOMPOSITION_DO_NOT_RECURSE1 (1ull << 45)++KBTS_INLINE kbts_u8 kbts__GetSyllabicClass(kbts_u16 SyllabicInfo)+{+ return SyllabicInfo & 0xFF;+}++KBTS_INLINE kbts_u8 kbts__GetSyllabicPosition(kbts_u16 SyllabicInfo)+{+ return SyllabicInfo >> 8;+}++KBTS_INLINE kbts_s32 *kbts__GetParentInfoDeltas(kbts_u32 ParentInfo)+{+ return kbts__UnicodeParentDeltas + (ParentInfo & 0xFFFF);+}++KBTS_INLINE kbts_un kbts__GetParentInfoCount(kbts_u32 ParentInfo)+{+ return ParentInfo >> 16;+}++KBTS_INLINE kbts_un kbts__ScriptExtensionCount(kbts_u16 ScriptExtension)+{+ return (ScriptExtension & 0x1f);+}++KBTS_INLINE kbts_un kbts__ScriptExtensionOffset(kbts_u16 ScriptExtension)+{+ return (ScriptExtension >> 5);+}++typedef kbts_u8 kbts_grapheme_break_class;+enum kbts_grapheme_break_class_enum {+ /* 0 */ KBTS_GRAPHEME_BREAK_CLASS_DEFAULT,+ /* 1 */ KBTS_GRAPHEME_BREAK_CLASS_CR,+ /* 2 */ KBTS_GRAPHEME_BREAK_CLASS_LF,+ /* 3 */ KBTS_GRAPHEME_BREAK_CLASS_Control,+ /* 4 */ KBTS_GRAPHEME_BREAK_CLASS_Extend,+ /* 5 */ KBTS_GRAPHEME_BREAK_CLASS_ZWJ,+ /* 6 */ KBTS_GRAPHEME_BREAK_CLASS_SpacingMark,+ /* 7 */ KBTS_GRAPHEME_BREAK_CLASS_L,+ /* 8 */ KBTS_GRAPHEME_BREAK_CLASS_V,+ /* 9 */ KBTS_GRAPHEME_BREAK_CLASS_LV,+ /* 10 */ KBTS_GRAPHEME_BREAK_CLASS_LVT,+ /* 11 */ KBTS_GRAPHEME_BREAK_CLASS_T,+ /* 12 */ KBTS_GRAPHEME_BREAK_CLASS_Prepend,+ /* 13 */ KBTS_GRAPHEME_BREAK_CLASS_IndicConsonant,+ /* 14 */ KBTS_GRAPHEME_BREAK_CLASS_IndicExtend,+ /* 15 */ KBTS_GRAPHEME_BREAK_CLASS_IndicLinker,+ /* 16 */ KBTS_GRAPHEME_BREAK_CLASS_ExtendedPictographic,+ /* 17 */ KBTS_GRAPHEME_BREAK_CLASS_RI,++ KBTS_GRAPHEME_BREAK_CLASS_COUNT,+};++typedef kbts_u8 kbts_grapheme_break_state;+enum kbts_grapheme_break_state_enum {+ /* 0 */ KBTS_GRAPHEME_BREAK_STATE_START,+ /* 1 */ KBTS_GRAPHEME_BREAK_STATE_CR,+ /* 2 */ KBTS_GRAPHEME_BREAK_STATE_L,+ /* 3 */ KBTS_GRAPHEME_BREAK_STATE_LVxV,+ /* 4 */ KBTS_GRAPHEME_BREAK_STATE_LVTxT,+ /* 5 */ KBTS_GRAPHEME_BREAK_STATE_IndicConsonantxIndicLinker,+ /* 6 */ KBTS_GRAPHEME_BREAK_STATE_IndicExtendr,+ /* 7 */ KBTS_GRAPHEME_BREAK_STATE_IndicExtendLinkerr,+ /* 8 */ KBTS_GRAPHEME_BREAK_STATE_ExtendedPictographic,+ /* 9 */ KBTS_GRAPHEME_BREAK_STATE_ExtendR,+ /* 10 */ KBTS_GRAPHEME_BREAK_STATE_ExtendR_ZWJ,+ /* 11 */ KBTS_GRAPHEME_BREAK_STATE_RI,+ /* 12 */ KBTS_GRAPHEME_BREAK_STATE_SKIP,++ /* 13 */ KBTS_GRAPHEME_BREAK_STATE_COUNT,++ /* 14 */ KBTS_GRAPHEME_BREAK_STATE_b0,+ /* 15 */ KBTS_GRAPHEME_BREAK_STATE_b01,+ // The values below have to be in the same order as their corresponding states.+ /* 16 */ KBTS_GRAPHEME_BREAK_STATE_b1,+ /* 17 */ KBTS_GRAPHEME_BREAK_STATE_b1toCR,+ /* 18 */ KBTS_GRAPHEME_BREAK_STATE_b1toL,+ /* 19 */ KBTS_GRAPHEME_BREAK_STATE_b1toLVxV,+ /* 20 */ KBTS_GRAPHEME_BREAK_STATE_b1toLVTxT,+ /* 21 */ KBTS_GRAPHEME_BREAK_STATE_b1toIndicConsonantxIndicLinker,+ /* 22 */ KBTS_GRAPHEME_BREAK_STATE_PADDING0,+ /* 23 */ KBTS_GRAPHEME_BREAK_STATE_PADDING1,+ /* 24 */ KBTS_GRAPHEME_BREAK_STATE_b1toExtendedPictographic,+ /* 25 */ KBTS_GRAPHEME_BREAK_STATE_PADDING2,+ /* 26 */ KBTS_GRAPHEME_BREAK_STATE_PADDING3,+ /* 27 */ KBTS_GRAPHEME_BREAK_STATE_b1toRI,+ /* 28 */ KBTS_GRAPHEME_BREAK_STATE_b1toSKIP,+};++// In the SKIP column, CR, LF and Control all still break before the cursor+// because their rules have a higher priority.+// In Indic-related states, ZWJ should behave like an Indic Extend.+static kbts_grapheme_break_state kbts_GraphemeBreakTransition[KBTS_GRAPHEME_BREAK_CLASS_COUNT][KBTS_GRAPHEME_BREAK_STATE_COUNT] = {+ /* 0 1 2 3 4 5 6 7 8 9 10 11 12 */+ /* 0 */ {16,16,16,16,16,16,16,16,16,16,16,16, 0},+ /* 1 */ {17,17,17,17,17,17,17,17,17,17,17,17,17},+ /* 2 */ {15,14,15,15,15,15,15,15,15,15,15,15,15},+ /* 3 */ {15,15,15,15,15,15,15,15,15,15,15,15,15},+ /* 4 */ { 0,16, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0},+ /* 5 */ { 0,16, 0, 0, 0, 6, 6, 7,10,10, 0, 0, 0},+ /* 6 */ { 0,16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},+ /* 7 */ {18,18, 2,18,18,18,18,16,18,18,18,18, 2},+ /* 8 */ {19,19, 3, 3,19,19,19,16,19,19,19,19, 3},+ /* 9 */ {19,19, 3,19,19,19,19,16,19,19,19,19, 3},+ /* 10 */ {20,20, 4,20,20,20,20,16,20,20,20,20, 4},+ /* 11 */ {20,20,20, 4, 4,20,20,16,20,20,20,20, 4},+ /* 12 */ {28,28,28,28,28,28,28,28,28,28,28,28,12},+ /* 13 */ {21,21,21,21,21,21,21, 5,21,21,21,21, 5},+ /* 14 */ { 0,16, 0, 0, 0, 6, 6, 7, 9, 9, 0, 0, 0},+ /* 15 */ { 5,21, 5, 5, 5, 7, 7, 7, 5, 5, 5, 5, 5},+ /* 16 */ {24,24,24,24,24,24,24,16,24,24, 0,24, 8},+ /* 17 */ {27,27,27,27,27,27,27,27,27,27,27, 0,11},+};++// These classes are for Indic, Myanmar and Khmer.+typedef kbts_u8 kbts_indic_syllabic_class;+enum kbts_indic_syllabic_class_enum {+ /* 0 A */ KBTS_INDIC_SYLLABIC_CLASS_OTHER,+ /* 1 B */ KBTS_INDIC_SYLLABIC_CLASS_CONSONANT,+ /* 2 C */ KBTS_INDIC_SYLLABIC_CLASS_VOWEL,+ /* 3 D */ KBTS_INDIC_SYLLABIC_CLASS_NUKTA,+ /* 4 E */ KBTS_INDIC_SYLLABIC_CLASS_HALANT,+ /* 5 F */ KBTS_INDIC_SYLLABIC_CLASS_ZWNJ,+ /* 6 G */ KBTS_INDIC_SYLLABIC_CLASS_ZWJ,+ /* 7 H */ KBTS_INDIC_SYLLABIC_CLASS_MATRA,+ /* 8 I */ KBTS_INDIC_SYLLABIC_CLASS_SYLLABLE_MODIFIER,+ /* 9 J */ KBTS_INDIC_SYLLABIC_CLASS_VEDIC_SIGN,+ /* 10 K */ KBTS_INDIC_SYLLABIC_CLASS_PLACEHOLDER,+ /* 11 L */ KBTS_INDIC_SYLLABIC_CLASS_DOTTED_CIRCLE,+ /* 12 M */ KBTS_INDIC_SYLLABIC_CLASS_REGISTER_SHIFTER,+ /* 13 N */ KBTS_INDIC_SYLLABIC_CLASS_MATRA_POST,+ /* 14 O */ KBTS_INDIC_SYLLABIC_CLASS_REPHA,+ /* 15 P */ KBTS_INDIC_SYLLABIC_CLASS_RA,+ /* 16 Q */ KBTS_INDIC_SYLLABIC_CLASS_CONSONANT_MEDIAL,+ /* 17 R */ KBTS_INDIC_SYLLABIC_CLASS_SYMBOL,+ /* 18 S */ KBTS_INDIC_SYLLABIC_CLASS_CONSONANT_WITH_STACKER,+ /* 19 T */ KBTS_INDIC_SYLLABIC_CLASS_SYLLABLE_MODIFIER_POST,+ /* 20 U */ KBTS_INDIC_SYLLABIC_CLASS_VOWEL_ABOVE,+ /* 21 V */ KBTS_INDIC_SYLLABIC_CLASS_VOWEL_BELOW,+ /* 22 W */ KBTS_INDIC_SYLLABIC_CLASS_VOWEL_PRE,+ /* 23 X */ KBTS_INDIC_SYLLABIC_CLASS_VOWEL_POST,+ /* 24 Y */ KBTS_INDIC_SYLLABIC_CLASS_ROBATIC,+ /* 25 Z */ KBTS_INDIC_SYLLABIC_CLASS_X_GROUP,+ /* 26 a */ KBTS_INDIC_SYLLABIC_CLASS_Y_GROUP,+ /* 27 b */ KBTS_INDIC_SYLLABIC_CLASS_ASAT,+ /* 28 c */ KBTS_INDIC_SYLLABIC_CLASS_DOT_BELOW,+ /* 29 d */ KBTS_INDIC_SYLLABIC_CLASS_SYLLABLE_MOD,+ /* 30 e */ KBTS_INDIC_SYLLABIC_CLASS_MEDIAL_HA,+ /* 31 f */ KBTS_INDIC_SYLLABIC_CLASS_MEDIAL_RA,+ /* 32 g */ KBTS_INDIC_SYLLABIC_CLASS_MEDIAL_WA,+ /* 33 h */ KBTS_INDIC_SYLLABIC_CLASS_MEDIAL_YA,+ /* 34 i */ KBTS_INDIC_SYLLABIC_CLASS_PWO,+ /* 35 j */ KBTS_INDIC_SYLLABIC_CLASS_VARIATION_SELECTOR,+ /* 36 k */ KBTS_INDIC_SYLLABIC_CLASS_MEDIAL_MON_LA,++ KBTS_MYANMAR_SYLLABIC_CLASS_COUNT,+ KBTS_INDIC_SYLLABIC_CLASS_COUNT = KBTS_INDIC_SYLLABIC_CLASS_SYLLABLE_MODIFIER_POST + 1,+ KBTS_KHMER_SYLLABIC_CLASS_COUNT = KBTS_INDIC_SYLLABIC_CLASS_Y_GROUP + 1,+};++#define KBTS_INDIC_SYLLABIC_STATE_COUNT 41+#define KBTS_MYANMAR_SYLLABIC_STATE_COUNT 31+#define KBTS_KHMER_SYLLABIC_STATE_COUNT 23++// @Incomplete: Decrement every state by 1.+static kbts_u8 kbts_IndicSyllabicTransition[KBTS_INDIC_SYLLABIC_CLASS_COUNT][KBTS_INDIC_SYLLABIC_STATE_COUNT] = {+ /* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 */+ /* A */ {43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,},+ /* B */ {14,43,43,43,43,43,43,14,43,43,43,43,43,43,43,14,43,14,43,43,43,43,43,43,43,14,43,43,43,43,43,43,14,43,43,14,43,43,14,43,14,},+ /* C */ {30,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,30,43,43,43,43,43,43,43,43,43,43,43,43,30,43,43,},+ /* D */ {24,43,24,20,43,43,31,43,43,43, 7,43,43,24,43,33,43,43,43,43,43,43,43,12,43,24,43,43,43, 7,43,24,43,43,43,33,15,43,24,24,43,},+ /* E */ { 8,43, 8,21,27,43, 8,43,18,18, 8, 8,18, 8,43,43,43,43,43,21,43,43,43, 8,18, 8,43,38,43, 8, 8, 8,43,43,18,18,43,43, 8,26,43,},+ /* F */ {25,43,13,22,28, 2,13,15,19,19,13,13,19,25,29,29, 2,29,19,22,22,19, 2,13,19,35,15,19,43, 9,13,25,29,43,22,22,29,29,25,25,43,},+ /* G */ {13,43,13,22,28,43,10,16,19,19,10,13,19,32,29,29,43,16,19,22,22,19,43,13,19,36,37,19,43,10,10,13,29,43,22,22,29,37,13,32,43,},+ /* H */ { 4,43, 4, 4, 4,43, 4,43, 4, 4, 4, 4, 4, 4,43,43,43,43, 4, 4, 4, 4,43, 4, 4, 4,43, 4,43, 4, 4, 4,43,43, 4, 4,43,43, 4, 4,43,},+ /* I */ { 6,43, 6, 6, 6,23, 6,17, 6, 6, 6, 6, 6, 6,17,17,23,17,34, 6, 6, 6,43, 6, 6, 6,17, 6,17, 6, 6, 6,17,43, 6, 6,17,17, 6, 6,43,},+ /* J */ { 2, 2, 2, 2, 2, 2, 2, 2,43,43, 2, 2,43, 2, 2, 2, 2, 2,43, 2, 2,43, 2, 2,43, 2, 2,43,43, 2, 2, 2, 2,43, 2, 2, 2, 2, 2, 2,43,},+ /* K */ {32,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,32,43,32,},+ /* L */ {32,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,32,43,43,43,43,43,43,43,43,43,43,43,43,32,43,43,},+ /* M */ { 3,43,43,43,43,43,43,43,11,43,43,43,43, 3,43,43,43,43,43,43,43,43,43,43, 3, 3,43,43,43,11,43, 3,43,43, 3,43,43,43, 3, 3,43,},+ /* N */ { 4,43, 4, 4, 4, 4, 4,43, 4, 4, 4, 4, 4, 4,43,43,43,43, 4, 4, 4, 4,43, 4, 4, 4,43, 4,43, 4, 4, 4,43, 4, 4, 4,43,43, 4, 4,43,},+ /* O */ {39,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,},+ /* P */ {40,43,43,43,43,43,43,14,43,43,43,43,43,43,43,14,43,14,43,43,43,43,43,43,43,14,43,43,43,43,43,43,14,43,43,14,43,43,14,43,14,},+ /* Q */ { 5,43, 5,43,43,43, 5,43,43,43, 5, 5,43, 5,43,43,43,43,43,43,43,43,43, 5,43, 5,43,43,43, 5, 5, 5,43,43,43,43,43,43, 5, 5,43,},+ /* R */ {37,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,},+ /* S */ {41,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,},+ /* T */ { 6,43, 6, 6, 6,23, 6,17, 6, 6, 6, 6, 6, 6,17,17,23,17,34, 6, 6, 6,43, 6, 6, 6,17, 6,17, 6, 6, 6,17,43, 6, 6,17,17, 6, 6,43,},+};++// @Incomplete: Decrement every state by 1.+static kbts_u8 kbts_MyanmarSyllabicTransition[KBTS_MYANMAR_SYLLABIC_CLASS_COUNT][KBTS_MYANMAR_SYLLABIC_STATE_COUNT] = {+ /* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 */+ /* A */ {33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,},+ /* B */ {18,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,18,33,33,33,33,33,33,33,33,18,18,33,18,},+ /* C */ {33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,},+ /* D */ {33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,},+ /* E */ {19,33,33,33,33,33,33,33,33,33,33,33,33,33,33,28,33,28,19,29,33,33,33,33,33,33,33,18,19,28,18,},+ /* F */ { 2,33, 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,33, 2, 2,33,},+ /* G */ { 2,33, 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,33, 2, 2,33,},+ /* H */ {33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,},+ /* I */ { 3,33, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,33, 3, 3,33,},+ /* J */ { 4,33,33, 4, 4, 4, 4, 4, 4,33, 4, 4, 4, 4,15, 4, 4, 4, 4, 4, 4, 4, 4, 4,33, 4,33,33, 4, 4, 4,},+ /* K */ {18,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,18,33,18,},+ /* L */ {18,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,18,33,18,},+ /* M */ {33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,},+ /* N */ {33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,},+ /* O */ {33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,},+ /* P */ {30,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,18,33,33,33,33,33,33,33,33,18,18,33,18,},+ /* Q */ {33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,},+ /* R */ {33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,},+ /* S */ {31,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,},+ /* T */ { 3,33, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,33, 3, 3,33,},+ /* U */ { 5,33,33,33, 5,33, 5,22, 5,33, 5, 5, 5, 5,33, 5, 5, 5, 5, 5, 5,22,22,22,33, 5,33,33, 5, 5,33,},+ /* V */ { 6,33,33,33, 6, 6, 6,33, 6,33, 6, 6, 6, 6,33, 6, 6, 6, 6, 6, 6,33,33,33,33, 6,33,33, 6, 6,33,},+ /* W */ { 7,33,33,33,33,33, 7,33, 7,33, 7, 7, 7, 7,33, 7, 7, 7, 7, 7, 7,33,33,33,33, 7,33,33, 7, 7,33,},+ /* X */ { 8,33,33, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,33, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,33,33, 8, 8,33,},+ /* Y */ {33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,},+ /* Z */ {33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,},+ /* a */ {33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,},+ /* b */ { 9,33,33,33,33,33,33,23, 9,25,21,33,21,26, 3, 9,21, 9, 9, 9,33,33,23,23,33,33, 3,33, 9,20,33,},+ /* c */ {10,33,33,10,10,10,10,10,10,33,10,10,10,10,27,10,10,10,10,10,10,10,10,10,33,10,33,33,10,10,33,},+ /* d */ {33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,},+ /* e */ {11,33,33,33,33,33,33,24,11,33,33,11,11,11,33,11,33,11,11,11,33,33,33,33,33,11,33,33,11,11,33,},+ /* f */ {12,33,33,33,33,33,33,33,12,33,33,33,33,12,33,12,33,12,12,12,33,33,33,33,33,12,33,33,12,12,33,},+ /* g */ {13,33,33,33,33,33,33,33,13,33,33,13,33,13,33,13,33,13,13,13,33,33,33,33,33,13,33,33,13,13,33,},+ /* h */ {14,33,33,33,33,33,33,33,14,33,33,33,33,33,33,14,33,14,14,14,33,33,33,33,33,33,33,33,14,14,33,},+ /* i */ {15,33,15,15,15,15,15,15,15,15,15,15,15,15,33,15,15,15,15,15,15,15,15,15,15,15,15,33,15,15,33,},+ /* j */ {16,33,33,33,33,33,21,33,33,33,33,33,33,33,33,33,33,16,16,33,33,33,33,33,33,33,33,33,16,16,33,},+ /* k */ {17,33,33,33,33,33,33,23,17,33,17,17,17,17,33,17,33,17,17,17,33,33,33,23,33,17,33,33,17,17,33,},+};++// @Incomplete: Decrement every state by 1.+static kbts_u8 kbts_KhmerSyllabicTransition[KBTS_KHMER_SYLLABIC_CLASS_COUNT][KBTS_KHMER_SYLLABIC_STATE_COUNT] = {+ /* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 */+ /* A */ {25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,},+ /* B */ {15,25,25,25,25,18,25,25,25,25,25,25,25,25,25,25,25,25,25,25, 2,25,25,},+ /* C */ {15,25,25,25,25,18,25,25,25,25,25,25,25,25,25,25,25,25,25,25, 2,25,25,},+ /* D */ {25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,},+ /* E */ {21,21,25,25,21,25,25, 6,25, 6,25, 6,25, 6,21,21,25,25,25,25,25, 6,25,},+ /* F */ { 4,17, 3, 3, 4,25, 7, 7,19, 9,20,11,13,13,23, 4, 3,25,19,20,25, 4, 3,},+ /* G */ { 4,17, 3, 3, 4,25, 7, 7,19, 9,20,11,13,13,23, 4, 3,25,19,20,25, 4, 3,},+ /* H */ {25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,},+ /* I */ {25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,},+ /* J */ {25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,},+ /* K */ {16,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,},+ /* L */ {16,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,},+ /* M */ {25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,},+ /* N */ {25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,},+ /* O */ {25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,},+ /* P */ {15,25,25,25,25,18,25,25,25,25,25,25,25,25,25,25,25,25,25,25, 2,25,25,},+ /* Q */ {25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,},+ /* R */ {25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,},+ /* S */ {25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,},+ /* T */ {25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,},+ /* U */ { 8, 8,25, 8, 8,25,25,25, 8, 8, 8, 8,25,25, 8, 8, 8,25,25,25,25, 8, 8,},+ /* V */ {10,10,25,25,10,25,25,25,25,25,25,10,25,25,10,10,25,25,25,25,25,10,25,},+ /* W */ {12,12,25,25,12,25,25,25,25,25,25,25,25,25,12,12,25,25,25,25,25,12,25,},+ /* X */ {14,14,25,25,14,25,25,14,25,14,25,14,25,25,14,14,25,25,25,25,25,14,25,},+ /* Y */ { 5, 5,25,25,25,25,25,25,25,25,25,25,25,25,16, 5, 5,25,25,25,25,25,16,},+ /* Z */ {22,22,22,22,22,25, 8, 8,10,10,12,12,14,14,22,22,22,25,10,12,25,22,22,},+ /* a */ {18,18,25,25,18,25,25,18,25,18,25,18,25,18,18,18,25,18,25,25,25,18,25,},+};++typedef kbts_u8 kbts_use_syllabic_class;+enum kbts_use_syllabic_class_enum {+ /* 0 */ KBTS_USE_SYLLABIC_CLASS_OTHER,+ /* 1 */ KBTS_USE_SYLLABIC_CLASS_BASE,+ /* 2 */ KBTS_USE_SYLLABIC_CLASS_BASE_OTHER,+ /* 3 */ KBTS_USE_SYLLABIC_CLASS_HALANT,+ /* 4 */ KBTS_USE_SYLLABIC_CLASS_HALANT_OR_VOWEL_MODIFIER,+ /* 5 */ KBTS_USE_SYLLABIC_CLASS_SAKOT,+ /* 6 */ KBTS_USE_SYLLABIC_CLASS_INVISIBLE_STACKER,+ /* 7 */ KBTS_USE_SYLLABIC_CLASS_CONS_SUB,+ /* 8 */ KBTS_USE_SYLLABIC_CLASS_CONS_MOD_ABOVE,+ /* 9 */ KBTS_USE_SYLLABIC_CLASS_CONS_MOD_BELOW,+ /* 10 */ KBTS_USE_SYLLABIC_CLASS_CONS_MED_PRE,+ /* 11 */ KBTS_USE_SYLLABIC_CLASS_CONS_MED_ABOVE,+ /* 12 */ KBTS_USE_SYLLABIC_CLASS_CONS_MED_BELOW,+ /* 13 */ KBTS_USE_SYLLABIC_CLASS_CONS_MED_POST,+ /* 14 */ KBTS_USE_SYLLABIC_CLASS_CONS_FINAL_ABOVE,+ /* 15 */ KBTS_USE_SYLLABIC_CLASS_CONS_FINAL_BELOW,+ /* 16 */ KBTS_USE_SYLLABIC_CLASS_CONS_FINAL_POST,+ /* 17 */ KBTS_USE_SYLLABIC_CLASS_REORDERING_KILLER,+ /* 18 */ KBTS_USE_SYLLABIC_CLASS_HIEROGLYPH,+ /* 19 */ KBTS_USE_SYLLABIC_CLASS_HIEROGLYPH_SEGMENT_BEGIN,+ /* 20 */ KBTS_USE_SYLLABIC_CLASS_HIEROGLYPH_MOD,+ /* 21 */ KBTS_USE_SYLLABIC_CLASS_HIEROGLYPH_SEGMENT_END,+ /* 22 */ KBTS_USE_SYLLABIC_CLASS_HIEROGLYPH_JOINER,+ /* 23 */ KBTS_USE_SYLLABIC_CLASS_HIEROGLYPH_MIRROR,+ /* 24 */ KBTS_USE_SYLLABIC_CLASS_CONS_FINAL_MOD_ABOVE,+ /* 25 */ KBTS_USE_SYLLABIC_CLASS_CONS_FINAL_MOD_BELOW,+ /* 26 */ KBTS_USE_SYLLABIC_CLASS_CONS_FINAL_MOD_POST,+ /* 27 */ KBTS_USE_SYLLABIC_CLASS_SYMBOL_MOD_ABOVE,+ /* 28 */ KBTS_USE_SYLLABIC_CLASS_SYMBOL_MOD_BELOW,+ /* 29 */ KBTS_USE_SYLLABIC_CLASS_VOWEL_MOD_ABOVE,+ /* 30 */ KBTS_USE_SYLLABIC_CLASS_VOWEL_MOD_BELOW,+ /* 31 */ KBTS_USE_SYLLABIC_CLASS_VOWEL_MOD_POST,+ /* 32 */ KBTS_USE_SYLLABIC_CLASS_VOWEL_MOD_PRE,+ /* 33 */ KBTS_USE_SYLLABIC_CLASS_VOWEL_PRE,+ /* 34 */ KBTS_USE_SYLLABIC_CLASS_VOWEL_ABOVE,+ /* 35 */ KBTS_USE_SYLLABIC_CLASS_VOWEL_BELOW,+ /* 36 */ KBTS_USE_SYLLABIC_CLASS_VOWEL_POST,+ /* 37 */ KBTS_USE_SYLLABIC_CLASS_CONSONANT_WITH_STACKER,+ /* 38 */ KBTS_USE_SYLLABIC_CLASS_REPHA,+ /* 39 */ KBTS_USE_SYLLABIC_CLASS_ZWNJ,+ /* 40 */ KBTS_USE_SYLLABIC_CLASS_HALANT_NUM,+ /* 41 */ KBTS_USE_SYLLABIC_CLASS_BASE_NUM,++ KBTS_USE_SYLLABIC_CLASS_COUNT,+};++enum+{+ KBTS_USE_STATE_s0 = 42,+};++// @Incomplete: Decrement every state by 1.+static kbts_u8 kbts_UseTransition[KBTS_USE_SYLLABIC_CLASS_COUNT][KBTS_USE_STATE_s0] = {+ /* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 */+ /* A */ {24,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,},+ /* B */ {15,44,44,44,44,44,44,44,44,15,15,44,44,15,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,37,44,37,44,44,44,44,44,44,44,44,44,44,},+ /* C */ {24,44,44,44,44,44,44,44,44,15,15,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,},+ /* D */ {14,44,44,44,44,44,44,44,44,44,14,44,44,44,14,14,31,31,31,31,44,44,44,14,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,14,},+ /* E */ {14,44,44,44,44, 5, 5, 5, 5,44,14,44,44, 5,14,14,31,31,31,31,44,44,44,14,44,44,44,44,44,44, 5, 5,44,44,44,44,44,44,44,44,44,14,},+ /* F */ {14,30,30,30,30,30,30,30,30,44,14,44,44,30,14,14,32,32,32,32,44,44,44,14,44,44,44,44,44,44,30,30,44,44,44,44,30,44,44,44,44,14,},+ /* G */ {14,44,44,44,44,44,44,44,44,44,14,44,44,44,14,14,31,31,31,31,44,44,44,14,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,14,},+ /* H */ {15,44,44,44,44,44,44,44,44,44,15,44,44,44,15,15,44,44,44,44,44,44,44,15,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,15,},+ /* I */ {15,44,44,44,44,44,44,44,44,44,15,44,44,44,15,44,44,44,44,44,44,44,44,15,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,15,},+ /* J */ {16,44,44,44,44,44,44,44,44,44,16,44,44,44,16,16,44,44,44,44,44,44,44,16,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,16,},+ /* K */ {17,44,44,44,44,44,44,44,44,44,17,44,44,44,17,17,44,44,44,44,44,44,44,17,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,17,},+ /* L */ {18,44,44,44,44,44,44,44,44,44,18,44,44,44,18,18,18,44,44,44,44,44,44,18,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,18,},+ /* M */ {19,44,44,44,44,44,44,44,44,44,19,44,44,44,19,19,19,19,44,44,44,44,44,19,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,19,},+ /* N */ {20,44,44,44,44,44,44,44,44,44,20,44,44,44,20,20,20,20,20,44,44,44,44,20,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,20,},+ /* O */ {21,21,21,21,21,21,21,21,21,44,21,44,44,21,21,21,21,21,21,21,21,44,44,21,44,44,44,44,44,44,21,21,44,44,44,44,21,44,44,44,44,21,},+ /* P */ {22,22,22,22,22,22,22,22,22,44,22,44,44,22,22,22,22,22,22,22,22,22,44,22,44,44,44,44,44,44,22,22,44,44,44,44,22,44,44,44,44,22,},+ /* Q */ {23,23,23,23,23,23,23,23,23,44,23,44,44,23,23,23,23,23,23,23,23,23,23,23,44,44,44,44,44,44,23,23,44,44,44,44,23,44,44,44,44,23,},+ /* R */ {25,44,44,44,44,44,44,44,44,44,25,44,44,44,25,25,44,44,44,44,44,44,44,25,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,25,},+ /* S */ {41,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,38,44,41,44,44,44,44,44,41,},+ /* T */ {42,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,34,44,36,44,39,39,39,44,36,},+ /* U */ {44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,33,44,44,39,44,39,33,44,},+ /* V */ {44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,33,44,33,44,44,44,44,44,33,44,},+ /* W */ {44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,34,34,34,44,44,34,34,34,34,44,},+ /* X */ {44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,40,44,44,35,44,},+ /* Y */ {26,26,26,26,26,26,26,26,26,44,26,44,44,26,26,26,26,26,26,26,26,26,26,26,44,26,44,44,44,44,26,26,44,44,44,44,26,44,44,44,44,26,},+ /* Z */ {27,27,27,27,27,27,27,27,27,44,27,44,44,27,27,27,27,27,27,27,27,27,27,27,44,27,27,44,44,44,27,27,44,44,44,44,27,44,44,44,44,27,},+ /* a */ {25,25,25,25,25,25,25,25,25,44,25,44,44,25,25,25,25,25,25,25,25,25,25,25,44,44,44,44,44,44,25,25,44,44,44,44,25,44,44,44,44,25,},+ /* b */ {28,44,44,44,44,44,44,44,44,44,11,44,44,44,44,44,44,44,44,44,44,44,44,28,44,44,44,28,44,44,44,44,44,44,44,44,44,44,44,44,44,28,},+ /* c */ {29,44,44,44,44,44,44,44,44,44,29,44,44,44,44,44,44,44,44,44,44,44,44,29,44,44,44,29,29,44,44,44,44,44,44,44,44,44,44,44,44,29,},+ /* d */ { 2, 2,44,44, 2, 2, 2, 2, 2,44, 2,44,44, 2, 2, 2, 2, 2, 2, 2,44,44,44, 2,44,44,44,44,44,44, 2, 2,44,44,44,44,44,44,44,44,44, 2,},+ /* e */ { 3, 3, 3,44, 3, 3, 3, 3, 3,44, 3,44,44, 3, 3, 3, 3, 3, 3, 3,44,44,44, 3,44,44,44,44,44,44, 3, 3,44,44,44,44,44,44,44,44,44, 3,},+ /* f */ { 4, 4, 4,44, 4, 4, 4, 4, 4,44, 4,44,44, 4, 4, 4, 4, 4, 4, 4,44,44,44, 4,44,44,44,44,44,44, 4, 4,44,44,44,44,44,44,44,44,44, 4,},+ /* g */ { 5,44,44,44, 5, 5, 5, 5, 5,44, 5,44,44, 5, 5, 5, 5, 5, 5, 5,44,44,44, 5,44,44,44,44,44,44, 5, 5,44,44,44,44,44,44,44,44,44, 5,},+ /* h */ { 6,44,44,44,44, 6,44,44,44,44, 6,44,44,44, 6, 6, 6, 6, 6, 6,44,44,44, 6,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44, 6,},+ /* i */ { 7,44,44,44,44, 7, 7,44,44,44, 7,44,44,44, 7, 7, 7, 7, 7, 7,44,44,44, 7,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44, 7,},+ /* j */ { 8,44,44,44,44, 8, 8, 8,44,44, 8,44,44,44, 8, 8, 8, 8, 8, 8,44,44,44, 8,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44, 8,},+ /* k */ { 9,44,44,44,44, 9, 9, 9, 9,44, 9,44,44,44, 9, 9, 9, 9, 9, 9,44,44,44, 9,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44, 9,},+ /* l */ {10,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,},+ /* m */ {11,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,},+ /* n */ {44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,},+ /* o */ {12,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,},+ /* p */ {13,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,},+};++KBTS_EXPORT void kbts_FontCoverageTestBegin(kbts_font_coverage_test *Test, kbts_font *Font)+{+ Test->Font = Font;+ Test->BaseParentCount = 0;+ Test->BaseCodepoint = 0;+ Test->CurrentBaseError = 0;+ Test->Error = 0;+}++KBTS_EXPORT void kbts_FontCoverageTestCodepoint(kbts_font_coverage_test *Test, int Codepoint)+{+ if(!Test->Error)+ {+ kbts_u32 UCodepoint = (kbts_u32)Codepoint;+ int RecomposeBase = 0;++ if(!kbts__GetUnicodeCombiningClass(UCodepoint))+ {+ Test->Error |= Test->CurrentBaseError;+ Test->CurrentBaseError = 0;+ Test->BaseCodepoint = UCodepoint;++ RecomposeBase = 1;+ }+ else+ {+ kbts_u16 Id = (kbts_u16)kbts_CodepointToGlyphId(Test->Font, Codepoint);++ if(!Id)+ {+ KBTS__FOR(ParentIndex, 0, Test->BaseParentCount)+ {+ kbts_glyph_parent *Parent = &Test->BaseParents[ParentIndex];++ if(kbts__GetDecompositionCodepoint(Parent->Decomposition, 1) == UCodepoint)+ {+ Test->BaseCodepoint = Parent->Codepoint;+ RecomposeBase = 1;++ break;+ }+ }++ if(!RecomposeBase)+ {+ Test->Error = 1;+ }+ }+ }++ if(RecomposeBase)+ {+ kbts_u32 BaseCodepoint = Test->BaseCodepoint;+ kbts_u16 BaseId = (kbts_u16)kbts_CodepointToGlyphId(Test->Font, (int)Test->BaseCodepoint);+ kbts_un BaseParentCount = 0;++ int Done = 0;+ while(!Done)+ {+ kbts_u32 ParentInfo = kbts__GetUnicodeParentInfo(BaseCodepoint);+ kbts_s32 *ParentDeltas = kbts__GetParentInfoDeltas(ParentInfo);++ BaseParentCount = 0;++ Done = 1;++ KBTS__FOR(ParentIndex, 0, BaseParentCount)+ {+ kbts_glyph_parent Parent = KBTS__ZERO;+ Parent.Codepoint = BaseCodepoint + (kbts_u32)ParentDeltas[ParentIndex];+ Parent.Decomposition = kbts__GetUnicodeDecomposition(Parent.Codepoint);+ kbts_u16 RecompositionId = (kbts_u16)kbts_CodepointToGlyphId(Test->Font, (int)Parent.Codepoint);++ if(RecompositionId)+ {+ if(kbts__GetDecompositionSize(Parent.Decomposition) == 1)+ {+ BaseCodepoint = Parent.Codepoint;+ BaseId = RecompositionId;++ Done = 0;++ break;+ }+ else+ {+ Test->BaseParents[BaseParentCount++] = Parent;+ }+ }+ }+ }++ Test->BaseCodepoint = BaseCodepoint;+ Test->BaseParentCount = (kbts_u32)BaseParentCount;++ if(!BaseId)+ {+ Test->CurrentBaseError = 1;+ }+ }+ }+}++KBTS_EXPORT int kbts_FontCoverageTestEnd(kbts_font_coverage_test *Test)+{+ int Result = Test->CurrentBaseError | Test->Error;+ Test->Error = Result;+ return !Result;+}++typedef struct kbts__feature_override_header+{+ struct kbts__feature_override_header *Prev;+ struct kbts__feature_override_header *Next;+} kbts__feature_override_header;++typedef struct kbts__feature_override+{+ kbts__feature_override_header Header;++ kbts_u32 Tag;+ int Value;+} kbts__feature_override;++typedef struct kbts_glyph_config+{+ kbts__feature_set EnabledFeatures;+ kbts__feature_set DisabledFeatures;++ kbts_u32 ExtraOverrideCount;++ kbts_allocator_function *Allocator;+ void *AllocatorData;++ kbts__feature_override_header FeatureOverrideSentinel;+} kbts_glyph_config;++typedef struct kbts__arena_block+{+ kbts_arena_block_header Header;+ void *BaseAllocation; // For freeing++ kbts_un Size;+ kbts_un Used;++ // char Memory[Size]; // if Memory is NULL+} kbts__arena_block;++typedef struct kbts__arena_lifetime+{+ kbts_arena *Arena;+ kbts_arena_block_header *BlockHeader;+ kbts_un Used;+} kbts__arena_lifetime;++typedef struct kbts__glyph_list+{+ kbts_glyph *SentinelPrev;+ kbts_glyph *SentinelNext;+ kbts_glyph *OneBeforeFirst;+ kbts_glyph *OnePastLast;+} kbts__glyph_list;++typedef struct kbts__baked_feature+{+ kbts_u16 *Indices;+ kbts_u32 Count;+ kbts_u32 FeatureTag;+ kbts_u32 FeatureId;+ kbts_u32 SkipFlags;+ kbts_u32 GlyphFilter;+} kbts__baked_feature;++typedef struct kbts__baked_feature_stage+{+ kbts_u16 FeatureCount;+ kbts_u16 FeatureIndexCount;+ kbts__baked_feature *Features; // [FeatureCount]+ kbts_u16 *FeatureIndices; // [FeatureIndexCount]+} kbts__baked_feature_stage;++#define KBTS_MAX_SIMULTANEOUS_FEATURES 32+typedef struct kbts__shape_scratchpad+{+ kbts_arena *Arena;++ kbts__feature_set LookupFeatures;+ kbts__feature_set UserFeatures;+ kbts__feature_set ScratchFeatures;++ kbts__glyph_list Cluster;+ int RealCluster;+ int ClusterAtStartOfWord;++ kbts_glyph *LookupOnePastLastGlyph;+ kbts_u32 LookupOnePastLastGlyphIndex;++ kbts_u32 NextGlyphUid;++ kbts_u32 Ip;+ kbts__op_kind OpKind;+ kbts__feature_set *OpFeatures;++ kbts_direction RunDirection;++ kbts_u32 FeatureIndexIndex;+ kbts_u32 FeatureStagesRead;+ kbts_u16 BakedLookupSubtablesRead[KBTS_MAX_SIMULTANEOUS_FEATURES];++ kbts_u32 UnregisteredFeatureCount;+ kbts_feature_tag UnregisteredFeatureTags[KBTS_MAX_SIMULTANEOUS_FEATURES];++ kbts_shape_error Error;+} kbts__shape_scratchpad;++#define KBTS_CONTEXT_MAX_FONT_COUNT 32++typedef struct kbts__config_params+{+ kbts_u32 FontIndex;+ kbts_script Script;+ kbts_language Language;+} kbts__config_params;++#define KBTS__INPUT_CODEPOINT_FIRST_BLOCK_MSB 6+#define KBTS__INPUT_CODEPOINT_ONE_PAST_LAST_BLOCK_MSB 27++typedef struct kbts__existing_shape_config+{+ kbts_shape_config *Config;++ kbts_font *Font;+ kbts_script Script;+} kbts__existing_shape_config;++typedef kbts_u32 kbts__context_flags;+enum kbts__context_flags_enum+{+ KBTS__CONTEXT_FLAG_NONE,++ KBTS__CONTEXT_FLAG_MANUAL_SEGMENTATION = 1,+ KBTS__CONTEXT_FLAG_START_OF_MANUAL_RUN = 2,+ KBTS__CONTEXT_FLAG_USE_MANUAL_BREAK_INFO = 4,+};++typedef struct kbts__context_font+{+ kbts_font *Font;+ kbts__arena_lifetime Lifetime;+} kbts__context_font;++typedef struct kbts_shape_context+{+ kbts_arena PermanentArena;+ kbts_arena FontArena;+ kbts_arena ConfigArena;+ kbts_arena ScratchArena;++ kbts_allocator_function *SelfAllocator;+ void *SelfAllocatorData;++ kbts_shape_codepoint *LastGraphemeBreak;+ kbts_u32 LastGraphemeBreakIndex;+ kbts_u32 LastLineBreakIndex;+ kbts_u32 BreakStartIndex;++ kbts_u32 FontCount;+ kbts__context_font Fonts[KBTS_CONTEXT_MAX_FONT_COUNT];++ kbts__config_params *ConfigTableKeys;+ kbts_shape_config **ConfigTable;++ kbts__feature_override_header FeatureOverrideSentinel;+ kbts__feature_override_header FreeFeatureOverrideSentinel;++ kbts_un InputCodepointCount;+ int NextUserId;+ kbts_shape_codepoint *InputBlocks[KBTS__INPUT_CODEPOINT_ONE_PAST_LAST_BLOCK_MSB - KBTS__INPUT_CODEPOINT_FIRST_BLOCK_MSB];++ kbts_glyph_storage GlyphStorage;++ kbts__context_flags Flags;+ kbts_direction ManualRunDirection;+ kbts_script ManualRunScript;++ kbts_u32 BeginClusterIp;+ kbts_u32 BeginClusterFeatureStagesRead;+ kbts_glyph *TopLevelGlyph;++ kbts__feature_set *OpFeatures;+ kbts__feature_set ScratchFeatures;+ kbts__feature_set UserFeatures;+ kbts__feature_set UserFeaturesEnabled;++ kbts_glyph_config *CurrentGlyphConfig;+ int NeedNewGlyphConfig;++ kbts_direction ParagraphDirection;+ kbts_language Language;++ kbts_font *RunFont;+ kbts_script RunScript;+ // This may be different from ParagraphDirection if ParagraphDirection == KBTS_DIRECTION_DONT_KNOW.+ kbts_direction RunParagraphDirection;+ kbts_direction RunDirection;+ kbts_shape_codepoint_iterator RunCodepointIterator;+ int DoneShapingRuns;++ kbts_u32 ExistingShapeConfigCount;+ kbts__existing_shape_config ExistingShapeConfigs[32];++ kbts_break_state BreakState;++ kbts_u32 FrameCount;++ kbts_shape_error Error;+} kbts_shape_context;++typedef struct kbts__indic_script_properties+{+ kbts_u32 ViramaCodepoint;+ kbts_u8 BlwfPostOnly;+ kbts__reph_position RephPosition;+ kbts__reph_encoding RephEncoding;+ kbts__syllabic_position RightSideMatraPosition;+ kbts__syllabic_position AboveBaseMatraPosition;+ kbts__syllabic_position BelowBaseMatraPosition;+} kbts__indic_script_properties;++typedef struct kbts_shape_config+{+ kbts_allocator_function *Allocator;+ void *AllocatorData;++ kbts_font *Font;+ kbts_script Script;+ kbts_language Language;+ kbts__langsys *Langsys[KBTS_SHAPING_TABLE_COUNT];+ kbts__op_list OpList;++ kbts__feature_set Features;++ kbts_shaper Shaper;+ kbts_shaper_properties *ShaperProperties;++ kbts__indic_script_properties IndicScriptProperties;+ kbts__feature *Blwf;+ kbts__feature *Pref;+ kbts__feature *Pstf;+ kbts__feature *Locl;+ kbts__feature *Rphf;+ kbts__feature *Half;+ kbts__feature *Vatu;++ // Indic+ kbts_glyph Virama;++ kbts_glyph DottedCircle;+ kbts_glyph Whitespace;++ // Thai+ kbts_glyph Nikhahit;+ kbts_glyph SaraAa;++ kbts__baked_feature_stage *FeatureStages; // [OpList.FeatureStageCount]+} kbts_shape_config;++static const kbts_u8 kbts__CmapFormatPrecedence[14] = {1, 0, 1, 0, 2, 0, 1, 0, 3, 0, 3, 0, 4, 5};++static int kbts__ShaperClearsMarkAdvancesInPostGposFixup(kbts_u32 Shaper)+{+ int Result = (1 << Shaper) & ((1 << KBTS_SHAPER_ARABIC) | (1 << KBTS_SHAPER_DEFAULT) | (1 << KBTS_SHAPER_HEBREW));+ return Result;+}++static kbts__indic_script_properties kbts__IndicScriptProperties(kbts_u32 Script)+{+ kbts__indic_script_properties Result = KBTS__ZERO;++ switch(Script)+ {+ case KBTS_SCRIPT_DEVANAGARI:+ {+ Result.ViramaCodepoint = 0x94D;+ Result.RephPosition = KBTS__REPH_POSITION_BEFORE_POST;+ Result.RightSideMatraPosition = KBTS__SYLLABIC_POSITION_AFTER_SUBJOINED;+ Result.AboveBaseMatraPosition = KBTS__SYLLABIC_POSITION_AFTER_SUBJOINED;+ Result.BelowBaseMatraPosition = KBTS__SYLLABIC_POSITION_AFTER_SUBJOINED;+ }+ break;++ case KBTS_SCRIPT_BENGALI:+ {+ Result.ViramaCodepoint = 0x9CD;+ Result.RephPosition = KBTS__REPH_POSITION_AFTER_SUBJOINED;+ Result.RightSideMatraPosition = KBTS__SYLLABIC_POSITION_AFTER_POST;+ Result.BelowBaseMatraPosition = KBTS__SYLLABIC_POSITION_AFTER_SUBJOINED;+ }+ break;++ case KBTS_SCRIPT_GUJARATI:+ {+ Result.ViramaCodepoint = 0xACD;+ Result.RephPosition = KBTS__REPH_POSITION_BEFORE_POST;+ Result.RightSideMatraPosition = KBTS__SYLLABIC_POSITION_AFTER_POST;+ Result.AboveBaseMatraPosition = KBTS__SYLLABIC_POSITION_AFTER_SUBJOINED;+ Result.BelowBaseMatraPosition = KBTS__SYLLABIC_POSITION_AFTER_POST;+ }+ break;++ case KBTS_SCRIPT_GURMUKHI:+ {+ Result.ViramaCodepoint = 0xA4D;+ Result.RephPosition = KBTS__REPH_POSITION_BEFORE_SUBJOINED;+ Result.RightSideMatraPosition = KBTS__SYLLABIC_POSITION_AFTER_POST;+ Result.AboveBaseMatraPosition = KBTS__SYLLABIC_POSITION_AFTER_POST;+ Result.BelowBaseMatraPosition = KBTS__SYLLABIC_POSITION_AFTER_POST;+ }+ break;++ case KBTS_SCRIPT_KANNADA:+ {+ Result.ViramaCodepoint = 0xCCD;+ Result.BlwfPostOnly = 1;+ Result.AboveBaseMatraPosition = KBTS__SYLLABIC_POSITION_BEFORE_SUBJOINED;+ Result.BelowBaseMatraPosition = KBTS__SYLLABIC_POSITION_BEFORE_SUBJOINED;+ }+ break;++ case KBTS_SCRIPT_MALAYALAM:+ {+ Result.ViramaCodepoint = 0xD4D;+ Result.RephPosition = KBTS__REPH_POSITION_AFTER_MAIN;+ Result.RephEncoding = KBTS__REPH_ENCODING_LOGICAL_REPHA;+ Result.RightSideMatraPosition = KBTS__SYLLABIC_POSITION_AFTER_POST;+ Result.BelowBaseMatraPosition = KBTS__SYLLABIC_POSITION_AFTER_POST;+ }+ break;++ case KBTS_SCRIPT_ODIA:+ {+ Result.ViramaCodepoint = 0xB4D;+ Result.RephPosition = KBTS__REPH_POSITION_AFTER_MAIN;+ Result.RightSideMatraPosition = KBTS__SYLLABIC_POSITION_AFTER_POST;+ Result.AboveBaseMatraPosition = KBTS__SYLLABIC_POSITION_AFTER_MAIN;+ Result.BelowBaseMatraPosition = KBTS__SYLLABIC_POSITION_AFTER_SUBJOINED;+ }+ break;++ case KBTS_SCRIPT_TAMIL:+ {+ Result.ViramaCodepoint = 0xBCD;+ Result.RightSideMatraPosition = KBTS__SYLLABIC_POSITION_AFTER_POST;+ Result.AboveBaseMatraPosition = KBTS__SYLLABIC_POSITION_AFTER_SUBJOINED;+ Result.BelowBaseMatraPosition = KBTS__SYLLABIC_POSITION_AFTER_POST;+ }+ break;++ case KBTS_SCRIPT_TELUGU:+ {+ Result.ViramaCodepoint = 0xC4D;+ Result.RephEncoding = KBTS__REPH_ENCODING_EXPLICIT;+ Result.BlwfPostOnly = 1;+ Result.AboveBaseMatraPosition = KBTS__SYLLABIC_POSITION_BEFORE_SUBJOINED;+ Result.BelowBaseMatraPosition = KBTS__SYLLABIC_POSITION_BEFORE_SUBJOINED;+ }+ break;+ }++ return Result;+}++static void kbts__ByteSwapArray16Unchecked(kbts_u16 *Array, kbts_un Count)+{+ KBTS__FOR(It, 0, Count)+ {+ Array[It] = kbts__ByteSwap16(Array[It]);+ }+}++static int kbts__ByteSwapArray16(kbts_u16 *Array, kbts_un Count, char *End)+{+ int Result = 0;+ if((char *)(Array + Count) <= End)+ {+ kbts__ByteSwapArray16Unchecked(Array, Count);+ Result = 1;+ }++ return Result;+}++static void kbts__ByteSwapArray32Unchecked(kbts_u32 *Array, kbts_un Count)+{+ KBTS__FOR(It, 0, Count)+ {+ Array[It] = kbts__ByteSwap32(Array[It]);+ }+}++static int kbts__ByteSwapArray32(kbts_u32 *Array, kbts_un Count, char *End)+{+ int Result = 0;+ if((char *)(Array + Count) <= End)+ {+ kbts__ByteSwapArray32Unchecked(Array, Count);+ Result = 1;+ }+ return Result;+}++static kbts_u64 kbts__ContainsFeature(kbts__feature_set *Set, kbts__feature_id Id)+{+ kbts_un WordIndex = Id / 64;+ kbts_un BitIndex = Id % 64;++ kbts_u64 Result = Set->Flags[WordIndex] & (1ull << BitIndex);+ return Result;+}++static void kbts__AddFeature(kbts__feature_set *Set, kbts__feature_id Id)+{+ kbts_un WordIndex = Id / 64;+ kbts_un BitIndex = Id % 64;++ Set->Flags[WordIndex] |= 1ull << BitIndex;+}++//+// TTF struct definitions.+//++enum+{+ KBTS__GLYPH_CLASS_BASE = 1,+ KBTS__GLYPH_CLASS_LIGATURE = 2,+ KBTS__GLYPH_CLASS_MARK = 3,+ KBTS__GLYPH_CLASS_COMPONENT = 4,+};++enum+{+ KBTS__LOOKUP_FLAG_RIGHT_TO_LEFT = 1 << 0,+ KBTS__LOOKUP_FLAG_IGNORE_BASE_GLYPHS = 1 << 1,+ KBTS__LOOKUP_FLAG_IGNORE_LIGATURES = 1 << 2,+ KBTS__LOOKUP_FLAG_IGNORE_MARKS = 1 << 3,+ KBTS__LOOKUP_FLAG_USE_MARK_FILTERING_SET = 1 << 4,++ KBTS__LOOKUP_FLAG_MARK_ATTACHMENT_CLASS_FILTER = 0xFF00,+};++enum+{+ KBTS__OS2_WIDTH_ULTRA_CONDENSED = 1,+ KBTS__OS2_WIDTH_EXTRA_CONDENSED = 2,+ KBTS__OS2_WIDTH_CONDENSED = 3,+ KBTS__OS2_WIDTH_SEMI_CONDENSED = 4,+ KBTS__OS2_WIDTH_MEDIUM = 5,+ KBTS__OS2_WIDTH_SEMI_EXPANDED = 6,+ KBTS__OS2_WIDTH_EXPANDED = 7,+ KBTS__OS2_WIDTH_EXTRA_EXPANDED = 8,+ KBTS__OS2_WIDTH_ULTRA_EXPANDED = 9,+};++enum+{+ KBTS__VALUE_FORMAT_X_PLACEMENT = 1 << 0,+ KBTS__VALUE_FORMAT_Y_PLACEMENT = 1 << 1,+ KBTS__VALUE_FORMAT_X_ADVANCE = 1 << 2,+ KBTS__VALUE_FORMAT_Y_ADVANCE = 1 << 3,+ KBTS__VALUE_FORMAT_X_PLACEMENT_DEVICE = 1 << 4,+ KBTS__VALUE_FORMAT_Y_PLACEMENT_DEVICE = 1 << 5,+ KBTS__VALUE_FORMAT_X_ADVANCE_DEVICE = 1 << 6,+ KBTS__VALUE_FORMAT_Y_ADVANCE_DEVICE = 1 << 7,+};++enum+{+ KBTS__OS2_SELECTION_FLAG_NONE,++ KBTS__OS2_SELECTION_FLAG_ITALIC = (1 << 0),+ KBTS__OS2_SELECTION_FLAG_UNDERSCORE = (1 << 1),+ KBTS__OS2_SELECTION_FLAG_NEGATIVE = (1 << 2),+ KBTS__OS2_SELECTION_FLAG_OUTLINED = (1 << 3),+ KBTS__OS2_SELECTION_FLAG_STRIKEOUT = (1 << 4),+ KBTS__OS2_SELECTION_FLAG_BOLD = (1 << 5),+ KBTS__OS2_SELECTION_FLAG_REGULAR = (1 << 6),+ KBTS__OS2_SELECTION_FLAG_USE_TYPO_METRICS = (1 << 7),+ KBTS__OS2_SELECTION_FLAG_WWS = (1 << 8),+ KBTS__OS2_SELECTION_FLAG_OBLIQUE = (1 << 9),+};++# pragma pack(push, 1)++typedef struct kbts__script_record+{+ kbts_u32 Tag;+ kbts_u16 Offset;+} kbts__script_record;++typedef struct kbts__script_list+{+ kbts_u16 Count;+ // kbts__script_record Records[Count];+} kbts__script_list;++typedef struct kbts__ot_script+{+ kbts_u16 DefaultLangsysOffset;+ kbts_u16 Count;+ // kbts__langsys_record Records[Count];+} kbts__ot_script;++typedef struct kbts__langsys_record+{+ kbts_u32 Tag;+ kbts_u16 Offset;+} kbts__langsys_record;++typedef struct kbts__langsys+{+ kbts_u16 LookupOrderOffset; // reserved+ kbts_u16 RequiredFeatureIndex;+ kbts_u16 FeatureIndexCount;+ // kbts_u16 FeatureIndices[FeatureIndexCount];+} kbts__langsys;++typedef struct kbts__feature_list+{+ kbts_u16 Count;+ // kbts__feature_record Records[Count];+} kbts__feature_list;++typedef struct kbts__feature_record+{+ kbts_u32 Tag;+ kbts_u16 Offset;+} kbts__feature_record;++typedef struct kbts__feature+{+ kbts_u16 FeatureParamsOffset;+ kbts_u16 LookupIndexCount;+ // kbts_u16 LookupIndices[LookupIndexCount];+} kbts__feature;++typedef struct kbts_lookup_list+{+ kbts_u16 Count;+ // kbts_u16 Offsets[Count];+} kbts_lookup_list;++// Lookups are used both in GSUB and GPOS.+// Type means either GSUB Lookup Type, or GPOS Lookup Type, depending on the table we are parsing.+typedef struct kbts__lookup+{+ kbts_u16 Type;+ kbts_u16 Flag;+ kbts_u16 SubtableCount;+ // kbts_u16 SubtableOffsets[SubtableCount];+ // If USE_MARK_FILTERING_SET:+ // kbts_u16 MarkFilteringSet;+} kbts__lookup;++typedef struct kbts__coverage+{+ kbts_u16 Format;+ kbts_u16 Count;+ // If Format == 1:+ // kbts_u16 GlyphArray[Count];+ // If Format == 2:+ // kbts__range_record Ranges[Count];+} kbts__coverage;++typedef struct kbts__range_record+{+ kbts_u16 StartGlyphId;+ kbts_u16 EndGlyphId;+ kbts_u16 StartCoverageIndex;+} kbts__range_record;++typedef struct kbts__class_definition_1+{+ kbts_u16 Format;+ kbts_u16 StartGlyphId;+ kbts_u16 GlyphCount;+ // kbts_u16 ClassValues[GlyphCount];+} kbts__class_definition_1;++typedef struct kbts__class_definition_2+{+ kbts_u16 Format;+ kbts_u16 Count;+ // kbts__class_range_record Ranges[Count];+} kbts__class_definition_2;++typedef struct kbts__class_range_record+{+ kbts_u16 StartGlyphId;+ kbts_u16 EndGlyphId;+ kbts_u16 Class;+} kbts__class_range_record;++typedef struct kbts__sequence_lookup_record+{+ kbts_u16 SequenceIndex;+ kbts_u16 LookupListIndex;+} kbts__sequence_lookup_record;++typedef struct kbts__sequence_rule+{+ kbts_u16 GlyphCount;+ kbts_u16 SequenceLookupCount;+ // kbts_u16 InputSequence[GlyphCount - 1];+ // kbts__sequence_lookup_record SequenceLookupRecords[SequenceLookupCount];+} kbts__sequence_rule;++typedef struct kbts__sequence_rule_set+{+ kbts_u16 Count;+ // kbts_u16 Offsets[Count];+} kbts__sequence_rule_set;++typedef struct kbts__sequence_context_1+{+ kbts_u16 Format;+ kbts_u16 CoverageOffset;+ kbts_u16 SeqRuleSetCount;+ // kbts_u16 SeqRuleSetOffsets[];+} kbts__sequence_context_1;++typedef struct kbts__sequence_context_2+{+ kbts_u16 Format;+ kbts_u16 CoverageOffset;+ kbts_u16 ClassDefOffset;+ kbts_u16 ClassSequenceRuleSetCount;+ // kbts_u16 ClassSequenceRuleSetOffsets[ClassSequenceRuleSetCount]; May be NULL!+} kbts__sequence_context_2;++typedef struct kbts__class_sequence_rule_set+{+ kbts_u16 Count;+ // kbts_u16 ClassSequenceRuleOffsets[Count];+} kbts__class_sequence_rule_set;++typedef struct kbts__class_sequence_rule+{+ kbts_u16 GlyphCount;+ kbts_u16 SequenceLookupCount;+ // kbts_u16 InputSequence[GlyphCount-1];+ // kbts__sequence_lookup_record SequenceLookupRecords[SequenceLookupCount];+} kbts__class_sequence_rule;++typedef struct kbts__sequence_context_3+{+ kbts_u16 Format;+ kbts_u16 GlyphCount;+ kbts_u16 SequenceLookupCount;+ // kbts_u16 CoverageOffsets[GlyphCount];+ // kbts__sequence_lookup_record SequenceLookupRecords[SequenceLookupCount];+} kbts__sequence_context_3;++typedef struct kbts__chained_sequence_context_1+{+ kbts_u16 Format;+ kbts_u16 CoverageOffset;+ kbts_u16 ChainedSequenceRuleSetCount;+ // kbts_u16 ChainedSequenceRuleSetOffsets[ChainedSequenceRuleSetCount];+} kbts__chained_sequence_context_1;++typedef struct kbts__chained_sequence_rule_set+{+ kbts_u16 Count;+ // kbts_u16 Offsets[Count];+} kbts__chained_sequence_rule_set;++typedef struct kbts__chained_sequence_rule+{+ kbts_u16 BacktrackGlyphCount;+ // kbts_u16 BacktrackSequence[BacktrackCount];+ // kbts_u16 InputGlyphCount;+ // kbts_u16 InputSequence[InputGlyphCount - 1];+ // kbts_u16 LookaheadGlyphCount;+ // kbts_u16 LookaheadSequence[LookaheadGlyphCount];+ // kbts_u16 SequenceLookupCount;+ // kbts__sequence_lookup_record SequenceLookupRecords[SequenceLookupCount];+} kbts__chained_sequence_rule;++typedef struct kbts__chained_sequence_context_2+{+ kbts_u16 Format;+ kbts_u16 CoverageOffset;+ kbts_u16 BacktrackClassDefOffset;+ kbts_u16 InputClassDefOffset;+ kbts_u16 LookaheadClassDefOffset;+ kbts_u16 ChainedClassSequenceRuleSetCount;+ // kbts_u16 ChainedClassSequenceRuleSetOffsets[ChainedClassSequenceRuleSetCount];+} kbts__chained_sequence_context_2;++typedef struct kbts__chained_sequence_context_3+{+ kbts_u16 Format;+ kbts_u16 BacktrackGlyphCount;+ // kbts_u16 BacktrackCoverageOffsets[BacktrackGlyphCount];+ // kbts_u16 InputGlyphCount;+ // kbts_u16 InputCoverageOffsets[InputGlyphCount];+ // kbts_u16 LookaheadGlyphCount;+ // kbts_u16 LookaheadCoverageOffsets[LookaheadGlyphCount];+ // kbts_u16 SequenceLookupCount;+ // kbts__sequence_lookup_record SequenceLookupRecords[SequenceLookupCount];+} kbts__chained_sequence_context_3;++typedef struct kbts__device+{+ union+ {+ struct+ {+ kbts_u16 StartSize;+ kbts_u16 EndSize;+ } Device;++ struct+ {+ kbts_u16 DeltaSetOuterIndex;+ kbts_u16 DeltaSetInnerIndex;+ } VariationIndex;+ } U;+ kbts_u16 DeltaFormat;+ // kbts_u16 DeltaValue[];+} kbts__device;++typedef struct kbts__feature_variations+{+ kbts_u16 Major;+ kbts_u16 Minor;+ kbts_u32 RecordCount;+ // kbts__feature_variation_record Records[RecordCount];+} kbts__feature_variations;++typedef struct kbts__feature_variation_record+{+ kbts_u32 ConditionSetOffset;+ kbts_u32 FeatureTableSubstitutionOffset;+} kbts__feature_variation_record;++typedef struct kbts__condition_set+{+ kbts_u16 Count;+ // kbts_u32 Offsets[Count];+} kbts__condition_set;++typedef struct kbts__condition_1+{+ kbts_u16 Format;+ kbts_u16 AxisIndex;+ kbts_u16 FilterRangeMinValue;+ kbts_u16 FilterRangeMaxValue;+} kbts__condition_1;++typedef struct kbts__feature_table_substitution+{+ kbts_u16 Major;+ kbts_u16 Minor;+ kbts_u16 Count;+ // kbts__feature_table_substitution_record Records[Count];+} kbts__feature_table_substitution;++typedef struct kbts__feature_table_substitution_record+{+ kbts_u16 FeatureIndex;+ kbts_u32 AlternateFeatureOffset;+} kbts__feature_table_substitution_record;++typedef struct kbts__ttc_header+{+ kbts_u32 Magic; // ttcf+ kbts_u16 Major;+ kbts_u16 Minor;+ kbts_u32 FontCount;+ // kbts_u32 TableDirectoryOffsets[FontCount];++ // If Major == 2:+ // kbts_u32 DsigTag;+ // kbts_u32 DsigLength;+ // kbts_u32 DsigOffset;+} kbts__ttc_header;++typedef struct kbts__table_directory+{+ kbts_u32 Version;+ kbts_u16 TableCount;+ kbts_u16 SearchRange;+ kbts_u16 EntrySelector;+ kbts_u16 RangeShift;+ // kbts__table_record Records[TableCount];+} kbts__table_directory;++typedef struct kbts__table_record+{+ kbts_u32 Tag;+ kbts_u32 Checksum;+ kbts_u32 Offset;+ kbts_u32 Length;+} kbts__table_record;++typedef struct kbts__cmap+{+ kbts_u16 Version;+ kbts_u16 TableCount;+ // kbts__encoding_record Records[TableCount];+} kbts__cmap;++typedef struct kbts__encoding_record+{+ kbts_u16 PlatformId;+ kbts_u16 EncodingId;+ kbts_u32 SubtableOffset;+} kbts__encoding_record;++/* Precedence rules for cmap tables:+ - Tables are mutually exclusive, except for format 14 which completes the others.+ - 8, 10, 12 > 0, 2, 4, 6+ - Formats 4, 12, 13, 14 are used today.+ - Formats 4 and 12 are basic cmap tables.+ - Format 13 is for fallback fonts that want to map lots of codepoints to a few fallback glyphs.+ - Format 14 is for Unicode Variation Sequences.+ - There can be Unicode and Windows tables with the same formats. In that case, we prefer the Windows tables.+*/++typedef struct kbts__cmap_0+{+ kbts_u16 Format;+ kbts_u16 Length;+ kbts_u16 Language;+ kbts_u8 GlyphIdArray[256];+} kbts__cmap_0;++typedef struct kbts__cmap_2+{+ kbts_u16 Format;+ kbts_u16 Length;+ kbts_u16 Language;+ kbts_u16 SubHeaderKeys[256];+ // kbts__sub_header SubHeaders[];+ // kbts_u16 GlyphIdArray[];+} kbts__cmap_2;++typedef struct kbts__sub_header+{+ kbts_u16 FirstCode;+ kbts_u16 EntryCount;+ kbts_s16 IdDelta;+ kbts_u16 IdRangeOffset;+} kbts__sub_header;++typedef struct kbts__cmap_4+{+ kbts_u16 Format;+ kbts_u16 Length;+ kbts_u16 Language;+ kbts_u16 SegmentCountTimesTwo;+ kbts_u16 SearchRange;+ kbts_u16 EntrySelector;+ kbts_u16 RangeShift;+ // kbts_u16 EndCode[SegmentCount];+ // kbts_u16 Reserved;+ // kbts_u16 StartCode[SegmentCount];+ // kbts_s16 IdDelta[SegmentCount];+ // kbts_u16 IdRangeOffsets[SegmentCount];+ // kbts_u16 GlyphIdArray[];+} kbts__cmap_4;++typedef struct kbts__cmap_6+{+ kbts_u16 Format;+ kbts_u16 Length;+ kbts_u16 Language;+ kbts_u16 FirstCode;+ kbts_u16 EntryCount;+ // kbts_u16 GlyphIdArray[EntryCount];+} kbts__cmap_6;++typedef struct kbts__cmap_12_13+{+ kbts_u16 Format;+ kbts_u16 Reserved;+ kbts_u32 Length;+ kbts_u32 Language;+ kbts_u32 GroupCount;+ // kbts__sequential_map_group Groups[GroupCount];+} kbts__cmap_12_13;++typedef struct kbts__sequential_map_group+{+ kbts_u32 StartCharacterCode;+ kbts_u32 EndCharacterCode;+ kbts_u32 StartGlyphId;+} kbts__sequential_map_group;++typedef struct kbts__cmap_14+{+ kbts_u16 Format;+ kbts_u32 Length;+ kbts_u32 SelectorCount;+ // kbts__variation_selector Selectors[SelectorCount];+} kbts__cmap_14;++typedef struct kbts__variation_selector+{+ kbts_u8 Selector[3];+ kbts_u32 DefaultUvsOffset;+ kbts_u32 NonDefaultUvsOffset;+} kbts__variation_selector;++typedef struct kbts__default_uvs+{+ kbts_u32 RangeCount;+ // kbts__unicode_range Ranges[RangeCount];+} kbts__default_uvs;++typedef struct kbts__unicode_range+{+ kbts_u8 Start[3];+ kbts_u8 Count;+} kbts__unicode_range;++typedef struct kbts__non_default_uvs+{+ kbts_u32 MappingCount;+ // kbts__uvs_mapping Mappings[MappingCount];+} kbts__non_default_uvs;++typedef struct kbts__uvs_mapping+{+ kbts_u8 UnicodeValue[3];+ kbts_u16 GlyphId;+} kbts__uvs_mapping;++typedef struct kbts__gsub_gpos+{+ kbts_u16 Major;+ kbts_u16 Minor;+ kbts_u16 ScriptListOffset;+ kbts_u16 FeatureListOffset;+ kbts_u16 LookupListOffset;+ kbts_u32 FeatureVariationsOffset; // Only present in v1.1+} kbts__gsub_gpos;++typedef struct kbts__single_substitution+{+ kbts_u16 Format;+ kbts_u16 CoverageOffset;+ union+ {+ kbts_s16 DeltaGlyphId; // Format == 1+ kbts_u16 GlyphCount; // Format == 2+ } DeltaOrCount;+ // If Format == 2:+ // kbts_u16 SubstituteGlyphIds[GlyphCount];+} kbts__single_substitution;++typedef struct kbts__multiple_substitution+{+ kbts_u16 Format;+ kbts_u16 CoverageOffset;+ kbts_u16 SequenceCount;+ // kbts_u16 SequenceOffsets[SequenceCount];+} kbts__multiple_substitution;++typedef struct kbts__sequence+{+ kbts_u16 GlyphCount;+ // kbts_u16 SubstituteGlyphIds[GlyphCount];+} kbts__sequence;++typedef struct kbts__alternate_substitution+{+ kbts_u16 Format;+ kbts_u16 CoverageOffset;+ kbts_u16 AlternateSetCount;+ // kbts_u16 AlternateSetOffsets[AlternateSetCount];+} kbts__alternate_substitution;++typedef struct kbts__alternate_set+{+ kbts_u16 GlyphCount;+ // kbts_u16 AlternateGlyphIds[GlyphCount];+} kbts__alternate_set;++typedef struct kbts__ligature_substitution+{+ kbts_u16 Format;+ kbts_u16 CoverageOffset;+ kbts_u16 LigatureSetCount;+ // kbts_u16 LigatureSetOffsets[LigatureSetCount];+} kbts__ligature_substitution;++typedef struct kbts__ligature_set+{+ kbts_u16 Count;+ // kbts_u16 Offsets[Count];+} kbts__ligature_set;++typedef struct kbts__ligature+{+ kbts_u16 Glyph;+ kbts_u16 ComponentCount;+ // kbts_u16 ComponentGlyphIds[ComponentCount - 1];+} kbts__ligature;++typedef struct kbts__extension+{+ kbts_u16 Format;+ kbts_u16 LookupType;+ kbts_u32 Offset;+} kbts__extension;++typedef struct kbts__reverse_chain_substitution+{+ kbts_u16 Format;+ kbts_u16 CoverageOffset;+ kbts_u16 BacktrackGlyphCount;+ // kbts_u16 BacktrackCoverageOffsets[BacktrackGlyphCount];+ // kbts_u16 LookaheadGlyphCount;+ // kbts_u16 LookaheadCoverageOffsets[LookaheadGlyphCount];+ // kbts_u16 GlyphCount;+ // kbts_u16 SubstituteGlyphIds[GlyphCount];+} kbts__reverse_chain_substitution;++typedef struct kbts__mark_glyph_sets+{+ kbts_u16 Format;+ kbts_u16 MarkGlyphSetCount;+ // kbts_u32 CoverageOffsets[MarkGlyphSetCount];+} kbts__mark_glyph_sets;++typedef struct kbts__gdef+{+ kbts_u16 Major;+ kbts_u16 Minor;+ kbts_u16 ClassDefinitionOffset; // May be 0+ kbts_u16 AttachListOffset; // May be 0+ kbts_u16 LigatureCaretListOffset; // May be 0+ kbts_u16 MarkAttachmentClassDefinitionOffset; // May be 0+ kbts_u16 MarkGlyphSetsDefinitionOffset; // v1.2 and up; may be 0+ kbts_u32 ItemVariationStoreOffset; // v1.3 and up; may be 0+} kbts__gdef;++typedef struct kbts__anchor+{+ kbts_u16 Format;+ kbts_s16 X;+ kbts_s16 Y;+ union+ {+ kbts_u16 AnchorPoint; // If Format == 2+ kbts_u16 XDeviceOffset; // If Format == 3+ } U;+ kbts_u16 YDeviceOffset; // If Format == 3+} kbts__anchor;++typedef struct kbts__mark_record+{+ kbts_u16 Class;+ kbts_u16 AnchorOffset;+} kbts__mark_record;++typedef struct kbts__mark_array+{+ kbts_u16 Count;+ // kbts__mark_record Records[Count];+} kbts__mark_array;++typedef struct kbts__single_adjustment_1+{+ kbts_u16 Format;+ kbts_u16 CoverageOffset;+ kbts_u16 ValueFormat;+ // ValueRecord;+} kbts__single_adjustment_1;++typedef struct kbts__single_adjustment_2+{+ kbts_u16 Format;+ kbts_u16 CoverageOffset;+ kbts_u16 ValueFormat;+ kbts_u16 RecordCount;+ // ValueRecord Records[RecordCount];+} kbts__single_adjustment_2;++typedef struct kbts__pair_value_record+{+ kbts_u16 SecondGlyph;+ // ValueRecord Record1;+ // ValueRecord Record2;+} kbts__pair_value_record;++typedef struct kbts__pair_set+{+ kbts_u16 Count;+ // kbts__pair_value_record PairValueRecords[Count];+} kbts__pair_set;++typedef struct kbts__pair_adjustment_1+{+ kbts_u16 Format;+ kbts_u16 CoverageOffset;+ kbts_u16 ValueFormat1; // May be 0+ kbts_u16 ValueFormat2; // May be 0+ kbts_u16 SetCount;+ // kbts_u16 SetOffsets[PairSetCount];+} kbts__pair_adjustment_1;++typedef struct kbts__pair_adjustment_2+{+ kbts_u16 Format;+ kbts_u16 CoverageOffset;+ kbts_u16 ValueFormat1; // May be 0+ kbts_u16 ValueFormat2; // May be 0+ kbts_u16 ClassDefinition1Offset;+ kbts_u16 ClassDefinition2Offset;+ kbts_u16 Class1Count;+ kbts_u16 Class2Count;+ // ValueRecord ValueRecords[Class1Count][Class2Count][2];+} kbts__pair_adjustment_2;++typedef struct kbts__entry_exit+{+ kbts_u16 EntryAnchorOffset;+ kbts_u16 ExitAnchorOffset;+} kbts__entry_exit;++typedef struct kbts__cursive_attachment+{+ kbts_u16 Format;+ kbts_u16 CoverageOffset;+ kbts_u16 EntryExitCount;+ // kbts__entry_exit Records[EntryExitCount];+} kbts__cursive_attachment;++typedef struct kbts__base_array+{+ kbts_u16 BaseCount;+ // kbts_u16 BaseAnchorOffsets[BaseCount][MarkClassCount]; // May be NULL+} kbts__base_array;++typedef struct kbts__mark_to_base_attachment+{+ kbts_u16 Format;+ kbts_u16 MarkCoverageOffset;+ kbts_u16 BaseCoverageOffset;+ kbts_u16 MarkClassCount;+ kbts_u16 MarkArrayOffset;+ kbts_u16 BaseArrayOffset;+} kbts__mark_to_base_attachment;++typedef struct kbts__ligature_attach+{+ kbts_u16 Count;+ // kbts_u16 LigatureAnchorOffsets[Count][MarkClassCount]; // May be NULL+} kbts__ligature_attach;++typedef struct kbts__ligature_array+{+ kbts_u16 Count;+ // kbts_u16 LigatureAttachOffsets[Count];+} kbts__ligature_array;++typedef struct kbts__mark_to_ligature_attachment+{+ kbts_u16 Format;+ kbts_u16 MarkCoverageOffset;+ kbts_u16 LigatureCoverageOffset;+ kbts_u16 MarkClassCount;+ kbts_u16 MarkArrayOffset;+ kbts_u16 LigatureArrayOffset;+} kbts__mark_to_ligature_attachment;++typedef struct kbts__long_mtx+{+ kbts_u16 Advance;+ kbts_s16 PreviousSideBearing;+} kbts__long_mtx;++struct kbts__head+{+ kbts_u16 Major;+ kbts_u16 Minor;+ kbts_u32 Revision;+ kbts_u32 ChecksumAdjustment;+ kbts_u32 MagicNumber;+ kbts_u16 Flags;+ kbts_u16 UnitsPerEm;+ kbts_s64 CreatedTime;+ kbts_s64 LastModifiedTime;+ kbts_s16 XMin;+ kbts_s16 YMin;+ kbts_s16 XMax;+ kbts_s16 YMax;+ kbts_u16 MacStyle; // OS/2 style takes priority on Windows.+ kbts_u16 LowestRecommendedPpem;+ kbts_s16 DirectionHint; // Deprecated. Should ~always be 2.+ kbts_s16 IndexToLocFormat;+ kbts_s16 GlyphDataFormat; // Only 0 is defined.+};++typedef struct kbts__hea+{+ kbts_u16 Major;+ kbts_u16 Minor;++ // According to Microsoft, these metrics are deprecated.+ // The OS/2 table is the preferred way to get these, now.+ kbts_s16 Ascent;+ kbts_s16 Descent;+ kbts_s16 LineGap;++ kbts_u16 MaxAdvance;+ kbts_s16 MinPreviousSideBearing;+ kbts_s16 MinNextSideBearing;+ kbts_s16 MaxExtent;++ kbts_s16 CaretSlopeRise;+ kbts_s16 CaretSlopeRun;+ kbts_s16 CaretOffset;++ kbts_u16 Reserved[4];++ kbts_s16 MetricDataFormat;+ kbts_u16 MetricCount;+} kbts__hea;++typedef struct kbts__os2+{+ kbts_u16 Version;+ kbts_s16 AverageCharacterWidth;+ kbts_u16 WeightClass;+ kbts_u16 WidthClass;+ kbts_u16 Type;+ kbts_s16 SubscriptXSize;+ kbts_s16 SubscriptYSize;+ kbts_s16 SubscriptXOffset;+ kbts_s16 SubscriptYOffset;+ kbts_s16 SuperscriptXSize;+ kbts_s16 SuperscriptYSize;+ kbts_s16 SuperscriptXOffset;+ kbts_s16 SuperscriptYOffset;+ kbts_s16 StrikeoutSize;+ kbts_s16 StrikeoutPosition;+ kbts_s16 FamilyClass;+ kbts_u8 Panose[10];+ kbts_u32 UnicodeRange[4];+ kbts_u32 VendorId;+ kbts_u16 Selection;+ kbts_u16 FirstCharacterIndex;+ kbts_u16 LastCharacterIndex;++ // Some version 0 fonts support this, others do not.+ kbts_s16 TypoAscender;+ kbts_s16 TypoDescender;+ kbts_s16 TypoLineGap;+ kbts_u16 WinAscent;+ kbts_u16 WinDescent;++ // If Version >= 1:+ kbts_u32 CodePageRange[2];++ // If Version >= 2:+ kbts_s16 Height;+ kbts_s16 CapHeight;+ kbts_u16 DefaultChar;+ kbts_u16 BreakChar;+ kbts_u16 MaxContext;++ // If Version >= 5:+ kbts_u16 LowerOpticalPointSize;+ kbts_u16 UpperOpticalPointSize;+} kbts__os2;++typedef struct kbts__lang_tag_record+{+ kbts_u16 Length;+ kbts_u16 LangTagOffset;+} kbts__lang_tag_record;++typedef struct kbts__name_record+{+ kbts_u16 PlatformId;+ kbts_u16 EncodingId;+ kbts_u16 LanguageId;+ kbts_u16 NameId;+ kbts_u16 Length;+ kbts_u16 StringOffset;+} kbts__name_record;++typedef struct kbts__name+{+ kbts_u16 Version;+ kbts_u16 Count;+ kbts_u16 StringStorageOffset;+ // kbts__name_record Records[Count];++ // If Version == 1:+ // kbts_u16 LangTagCount;+ // kbts__lang_tag_record LangTags[LangTagCount];+} kbts__name;++typedef struct kbts__maxp+{+ kbts_u16 Major;+ kbts_u16 Minor;+ kbts_u16 GlyphCount;++ // If Major == 1:+ kbts_u16 MaxPointCount;+ kbts_u16 MaxContourCount;+ kbts_u16 MaxCompositePointCount;+ kbts_u16 MaxCompositeContourCount;+ kbts_u16 MaxZoneCount;+ kbts_u16 MaxTwilightPointCount;+ kbts_u16 StorageAreaCount;+ kbts_u16 FunctionDefinitionCount;+ kbts_u16 InstructionDefinitionCount;+ kbts_u16 MaximumStackDepth;+ kbts_u16 MaximumInstructionSize;+ kbts_u16 MaximumTopLevelComponentCount;+ kbts_u16 MaximumComponentDepth;+} kbts__maxp;++# pragma pack(pop)++//+// Unpack functions for TTF structs.+//++typedef struct kbts__script_pointer+{+ kbts_u32 Tag;+ kbts__ot_script *Script;+} kbts__script_pointer;++typedef struct kbts__langsys_pointer+{+ kbts_u32 Tag;+ kbts__langsys *Langsys;+} kbts__langsys_pointer;++typedef struct kbts__feature_pointer+{+ kbts_u32 Tag;+ kbts__feature *Feature;+} kbts__feature_pointer;++typedef struct kbts__feature_variation_pointer+{+ kbts__condition_set *ConditionSet;+ kbts__feature_table_substitution *FeatureTableSubstitution;+} kbts__feature_variation_pointer;++typedef struct kbts__feature_substitution_pointer+{+ kbts_u16 SubstitutedFeatureIndex;+ kbts__feature *AlternateFeature;+} kbts__feature_substitution_pointer;++typedef struct kbts__cmap_subtable_pointer+{+ kbts_u16 PlatformId;+ kbts_u16 EncodingId;+ kbts_u16 *Subtable;+} kbts__cmap_subtable_pointer;++typedef struct kbts__unpacked_chained_sequence_rule+{+ kbts_u16 *Input;+ kbts_u16 *Backtrack;+ kbts_u16 *Lookahead;+ kbts__sequence_lookup_record *Records;++ kbts_u16 BacktrackCount;+ kbts_u16 InputCount;+ kbts_u16 LookaheadCount;+ kbts_u16 RecordCount;+} kbts__unpacked_chained_sequence_rule;++typedef struct kbts__unpacked_chained_sequence_context_3+{+ kbts_u16 *BacktrackCoverageOffsets;+ kbts_u16 *InputCoverageOffsets;+ kbts_u16 *LookaheadCoverageOffsets;+ kbts__sequence_lookup_record *Records;++ kbts_u16 BacktrackCount;+ kbts_u16 InputCount;+ kbts_u16 LookaheadCount;+ kbts_u16 RecordCount;+} kbts__unpacked_chained_sequence_context_3;++typedef struct kbts__unpacked_reverse_chain_substitution+{+ kbts_u16 *BacktrackCoverageOffsets;+ kbts_u16 *LookaheadCoverageOffsets;+ kbts_u16 *SubstituteGlyphIds;++ kbts_u16 BacktrackCount;+ kbts_u16 LookaheadCount;+ kbts_u16 GlyphCount;+} kbts__unpacked_reverse_chain_substitution;++typedef struct kbts__unpacked_value_record+{+ kbts_u16 Size;++ kbts_s16 PlacementX;+ kbts_s16 PlacementY;+ kbts_s16 AdvanceX;+ kbts_s16 AdvanceY;+ kbts__device *PlacementXDevice;+ kbts__device *PlacementYDevice;+ kbts__device *AdvanceXDevice;+ kbts__device *AdvanceYDevice;+} kbts__unpacked_value_record;++static kbts__unpacked_value_record kbts__UnpackValueRecord(void *Parent, kbts_u16 Format, kbts_u16 *Record)+{+ kbts__unpacked_value_record Result = KBTS__ZERO;++ kbts_u16 *At = Record;++ if(Format & KBTS__VALUE_FORMAT_X_PLACEMENT)+ {+ Result.PlacementX = (kbts_s16)*At++;+ }+ if(Format & KBTS__VALUE_FORMAT_Y_PLACEMENT)+ {+ Result.PlacementY = (kbts_s16)*At++;+ }+ if(Format & KBTS__VALUE_FORMAT_X_ADVANCE)+ {+ Result.AdvanceX = (kbts_s16)*At++;+ }+ if(Format & KBTS__VALUE_FORMAT_Y_ADVANCE)+ {+ Result.AdvanceY = (kbts_s16)*At++;+ }+ if(Format & KBTS__VALUE_FORMAT_X_PLACEMENT_DEVICE)+ {+ kbts_u16 Offset = *At++;++ if(Offset)+ {+ Result.PlacementXDevice = KBTS__POINTER_OFFSET(kbts__device, Parent, Offset);+ }+ }+ if(Format & KBTS__VALUE_FORMAT_Y_PLACEMENT_DEVICE)+ {+ kbts_u16 Offset = *At++;++ if(Offset)+ {+ Result.PlacementYDevice = KBTS__POINTER_OFFSET(kbts__device, Parent, Offset);+ }+ }+ if(Format & KBTS__VALUE_FORMAT_X_ADVANCE_DEVICE)+ {+ kbts_u16 Offset = *At++;++ if(Offset)+ {+ Result.AdvanceXDevice = KBTS__POINTER_OFFSET(kbts__device, Parent, Offset);+ }+ }+ if(Format & KBTS__VALUE_FORMAT_Y_ADVANCE_DEVICE)+ {+ kbts_u16 Offset = *At++;++ if(Offset)+ {+ Result.AdvanceYDevice = KBTS__POINTER_OFFSET(kbts__device, Parent, Offset);+ }+ }++ Result.Size = (kbts_u16)(At - Record);++ return Result;+}++static kbts__unpacked_reverse_chain_substitution kbts__UnpackReverseChainSubstitution(kbts__reverse_chain_substitution *Subst, int ByteSwap)+{+ kbts__unpacked_reverse_chain_substitution Result;++ Result.BacktrackCoverageOffsets = KBTS__POINTER_AFTER(kbts_u16, Subst);+ Result.BacktrackCount = Subst->BacktrackGlyphCount;+ if(ByteSwap)+ {+ Result.BacktrackCount = kbts__ByteSwap16(Result.BacktrackCount);+ }++ Result.LookaheadCoverageOffsets = Result.BacktrackCoverageOffsets + Result.BacktrackCount + 1;+ Result.LookaheadCount = Result.BacktrackCoverageOffsets[Result.BacktrackCount];+ if(ByteSwap)+ {+ Result.LookaheadCount = kbts__ByteSwap16(Result.LookaheadCount);+ }++ Result.SubstituteGlyphIds = Result.LookaheadCoverageOffsets + Result.LookaheadCount + 1;+ Result.GlyphCount = Result.LookaheadCoverageOffsets[Result.LookaheadCount];+ if(ByteSwap)+ {+ Result.GlyphCount = kbts__ByteSwap16(Result.GlyphCount);+ }++ return Result;+}++static kbts__unpacked_chained_sequence_rule kbts__UnpackChainedSequenceRule(kbts__chained_sequence_rule *Rule, int ByteSwap)+{+ kbts__unpacked_chained_sequence_rule Result;++ Result.Backtrack = KBTS__POINTER_AFTER(kbts_u16, Rule);+ Result.BacktrackCount = Rule->BacktrackGlyphCount;+ if(ByteSwap)+ {+ Result.BacktrackCount = kbts__ByteSwap16(Result.BacktrackCount);+ }++ Result.Input = Result.Backtrack + Result.BacktrackCount + 1;+ Result.InputCount = Result.Backtrack[Result.BacktrackCount];+ if(ByteSwap)+ {+ Result.InputCount = kbts__ByteSwap16(Result.InputCount);+ }++ Result.Lookahead = Result.Input + Result.InputCount;+ Result.LookaheadCount = Result.Input[Result.InputCount - 1];+ if(ByteSwap)+ {+ Result.LookaheadCount = kbts__ByteSwap16(Result.LookaheadCount);+ }++ Result.Records = (kbts__sequence_lookup_record *)(Result.Lookahead + Result.LookaheadCount + 1);+ Result.RecordCount = Result.Lookahead[Result.LookaheadCount];+ if(ByteSwap)+ {+ Result.RecordCount = kbts__ByteSwap16(Result.RecordCount);+ }++ return Result;+}++static kbts__unpacked_chained_sequence_context_3 kbts__UnpackChainedSequenceContext3(kbts__chained_sequence_context_3 *Subst, int ByteSwap)+{+ kbts__unpacked_chained_sequence_context_3 Result;++ Result.BacktrackCoverageOffsets = KBTS__POINTER_AFTER(kbts_u16, Subst);+ Result.BacktrackCount = Subst->BacktrackGlyphCount;+ if(ByteSwap)+ {+ Result.BacktrackCount = kbts__ByteSwap16(Result.BacktrackCount);+ }++ Result.InputCoverageOffsets = Result.BacktrackCoverageOffsets + Result.BacktrackCount + 1;+ Result.InputCount = Result.BacktrackCoverageOffsets[Result.BacktrackCount];+ if(ByteSwap)+ {+ Result.InputCount = kbts__ByteSwap16(Result.InputCount);+ }++ Result.LookaheadCoverageOffsets = Result.InputCoverageOffsets + Result.InputCount + 1;+ Result.LookaheadCount = Result.InputCoverageOffsets[Result.InputCount];+ if(ByteSwap)+ {+ Result.LookaheadCount = kbts__ByteSwap16(Result.LookaheadCount);+ }++ Result.Records = (kbts__sequence_lookup_record *)(Result.LookaheadCoverageOffsets + Result.LookaheadCount + 1);+ Result.RecordCount = Result.LookaheadCoverageOffsets[Result.LookaheadCount];+ if(ByteSwap)+ {+ Result.RecordCount = kbts__ByteSwap16(Result.RecordCount);+ }++ return Result;+}++typedef struct kbts__unpacked_lookup+{+ kbts_u16 *SubtableOffsets;+ kbts__coverage *MarkFilteringSet;+ kbts_u16 Type;+ kbts_u16 Flags;+ kbts_u16 SubtableCount;+} kbts__unpacked_lookup;++static kbts__unpacked_lookup kbts__UnpackLookup(kbts__gdef *Gdef, kbts__lookup *Lookup)+{+ kbts__unpacked_lookup Result = KBTS__ZERO;++ Result.Type = Lookup->Type;+ Result.Flags = Lookup->Flag;+ Result.SubtableCount = Lookup->SubtableCount;+ Result.SubtableOffsets = KBTS__POINTER_AFTER(kbts_u16, Lookup);+ if(Result.Flags & KBTS__LOOKUP_FLAG_USE_MARK_FILTERING_SET)+ {+ kbts_u16 MarkFilteringSetIndex = Result.SubtableOffsets[Result.SubtableCount];+ if(Gdef && Gdef->MarkGlyphSetsDefinitionOffset)+ {+ kbts__mark_glyph_sets *MarkGlyphSets = KBTS__POINTER_OFFSET(kbts__mark_glyph_sets, Gdef, Gdef->MarkGlyphSetsDefinitionOffset);+ if(MarkGlyphSets->MarkGlyphSetCount > MarkFilteringSetIndex)+ {+ kbts_u32 *CoverageOffsets = KBTS__POINTER_AFTER(kbts_u32, MarkGlyphSets);+ Result.MarkFilteringSet = KBTS__POINTER_OFFSET(kbts__coverage, MarkGlyphSets, CoverageOffsets[MarkFilteringSetIndex]);+ }+ }+ }++ return Result;+}++static kbts__script_pointer kbts__GetScript(kbts__script_list *List, kbts_un Index)+{+ kbts__script_record *Records = (kbts__script_record *)(List + 1);+ kbts__script_record *Record = &Records[Index];++ kbts__script_pointer Result;+ Result.Tag = Record->Tag;+ Result.Script = (kbts__ot_script *)((char *)List + Record->Offset);++ return Result;+}++static kbts__langsys *kbts__GetDefaultLangsys(kbts__ot_script *Script)+{+ kbts__langsys *Result = Script->DefaultLangsysOffset ? KBTS__POINTER_OFFSET(kbts__langsys, Script, Script->DefaultLangsysOffset) : 0;+ return Result;+}++static kbts__langsys_pointer kbts__GetLangsys(kbts__ot_script *Script, kbts_un Index)+{+ kbts__langsys_record *Records = (kbts__langsys_record *)(Script + 1);+ kbts__langsys_record *Record = &Records[Index];++ kbts__langsys_pointer Result;+ Result.Tag = Record->Tag;+ Result.Langsys = KBTS__POINTER_OFFSET(kbts__langsys, Script, Record->Offset);+ return Result;+}++static kbts__feature_pointer kbts__GetFeature(kbts__feature_list *List, kbts_un Index)+{+ kbts__feature_record *Records = (kbts__feature_record *)(List + 1);+ kbts__feature_record *Record = &Records[Index];++ kbts__feature_pointer Result;+ Result.Tag = Record->Tag;+ Result.Feature = KBTS__POINTER_OFFSET(kbts__feature, List, Record->Offset);+ return Result;+}++static kbts_lookup_list *kbts__GetLookupList(kbts__gsub_gpos *GsubGpos)+{+ kbts_lookup_list *Result = 0;++ if(GsubGpos)+ {+ Result = KBTS__POINTER_OFFSET(kbts_lookup_list, GsubGpos, GsubGpos->LookupListOffset);+ }++ return Result;+}++static kbts__lookup *kbts__GetLookup(kbts_lookup_list *List, kbts_un Index)+{+ KBTS_ASSERT(Index < List->Count);+ kbts_u16 *Offsets = (kbts_u16 *)(List + 1);+ kbts__lookup *Result = KBTS__POINTER_OFFSET(kbts__lookup, List, Offsets[Index]);+ return Result;+}++static kbts__sequence_rule_set *kbts__GetSequenceRuleSet(kbts__sequence_context_1 *Context, kbts_un Index)+{+ KBTS_ASSERT(Index < Context->SeqRuleSetCount);+ kbts_u16 *Offsets = (kbts_u16 *)(Context + 1);+ kbts_u16 Offset = Offsets[Index];++ kbts__sequence_rule_set *Result = Offset ? KBTS__POINTER_OFFSET(kbts__sequence_rule_set, Context, Offsets[Index]) : 0;+ return Result;+}++static kbts__sequence_rule *kbts__GetSequenceRule(kbts__sequence_rule_set *Set, kbts_un Index)+{+ KBTS_ASSERT(Index < Set->Count);+ kbts_u16 *Offsets = (kbts_u16 *)(Set + 1);+ kbts__sequence_rule *Result = KBTS__POINTER_OFFSET(kbts__sequence_rule, Set, Offsets[Index]);+ return Result;+}++// A single class definition table can be used by multiple lookups, so it is possible+// (and valid) to get an out-of-bounds glyph class.+static kbts__class_sequence_rule_set *kbts__GetClassSequenceRuleSet(kbts__sequence_context_2 *Context, kbts_un Index)+{+ kbts__class_sequence_rule_set *Result = 0;+ if(Index < Context->ClassSequenceRuleSetCount)+ {+ kbts_u16 *Offsets = (kbts_u16 *)(Context + 1);+ Result = Offsets[Index] ? KBTS__POINTER_OFFSET(kbts__class_sequence_rule_set, Context, Offsets[Index]) : 0;+ }+ return Result;+}++static kbts__class_sequence_rule *kbts__GetClassSequenceRule(kbts__class_sequence_rule_set *Set, kbts_un Index)+{+ KBTS_ASSERT(Index < Set->Count);+ kbts_u16 *Offsets = (kbts_u16 *)(Set + 1);+ kbts__class_sequence_rule *Result = KBTS__POINTER_OFFSET(kbts__class_sequence_rule, Set, Offsets[Index]);+ return Result;+}++static kbts__chained_sequence_rule_set *kbts__GetChainedSequenceRuleSet(kbts__chained_sequence_context_1 *Context, kbts_un Index)+{+ kbts_u16 *Offsets = (kbts_u16 *)(Context + 1);+ kbts__chained_sequence_rule_set *Result = Offsets[Index] ? KBTS__POINTER_OFFSET(kbts__chained_sequence_rule_set, Context, Offsets[Index]) : 0;+ return Result;+}++static kbts__chained_sequence_rule *kbts__GetChainedSequenceRule(kbts__chained_sequence_rule_set *Set, kbts_un Index)+{+ kbts_u16 *Offsets = (kbts_u16 *)(Set + 1);+ kbts__chained_sequence_rule *Result = KBTS__POINTER_OFFSET(kbts__chained_sequence_rule, Set, Offsets[Index]);+ return Result;+}++static kbts__chained_sequence_rule_set *kbts__GetChainedClassSequenceRuleSet(kbts__chained_sequence_context_2 *Context, kbts_un Index)+{+ kbts_u16 *Offsets = (kbts_u16 *)(Context + 1);+ kbts_u16 Offset = Offsets[Index];+ kbts__chained_sequence_rule_set *Result = Offset ? KBTS__POINTER_OFFSET(kbts__chained_sequence_rule_set, Context, Offset) : NULL;+ return Result;+}++static kbts__chained_sequence_rule *kbts__GetChainedClassSequenceRule(kbts__chained_sequence_rule_set *Set, kbts_un Index)+{+ kbts_u16 *Offsets = (kbts_u16 *)(Set + 1);+ kbts__chained_sequence_rule *Result = KBTS__POINTER_OFFSET(kbts__chained_sequence_rule, Set, Offsets[Index]);+ return Result;+}++#if 0 // @Incomplete+static kbts__feature_variation_pointer kbts__GetFeatureVariation(kbts__feature_variations *Variations, kbts_un Index)+{+ kbts__feature_variation_record *Records = (kbts__feature_variation_record *)(Variations + 1);+ kbts__feature_variation_record *Record = &Records[Index];++ kbts__feature_variation_pointer Result;+ Result.ConditionSet = KBTS__POINTER_OFFSET(kbts__condition_set, Variations, Record->ConditionSetOffset);+ Result.FeatureTableSubstitution = KBTS__POINTER_OFFSET(kbts__feature_table_substitution, Variations, Record->FeatureTableSubstitutionOffset);+ return Result;+}++static kbts__condition_1 *kbts__GetCondition(kbts__condition_set *Set, kbts_un Index)+{+ kbts_u32 *Offsets = (kbts_u32 *)(Set + 1);+ kbts__condition_1 *Result = KBTS__POINTER_OFFSET(kbts__condition_1, Set, Offsets[Index]);+ return Result;+}++static kbts__feature_substitution_pointer kbts__GetFeatureSubstitution(kbts__feature_table_substitution *Table, kbts_un Index)+{+ kbts__feature_table_substitution_record *Records = (kbts__feature_table_substitution_record *)(Table + 1);+ kbts__feature_table_substitution_record *Record = &Records[Index];++ kbts__feature_substitution_pointer Result;+ Result.SubstitutedFeatureIndex = Record->FeatureIndex;+ Result.AlternateFeature = KBTS__POINTER_OFFSET(kbts__feature, Table, Record->AlternateFeatureOffset);+ return Result;+}+#endif++static kbts__cmap_subtable_pointer kbts__GetCmapSubtable(kbts__cmap *Cmap, kbts_un Index)+{+ kbts__encoding_record *Records = (kbts__encoding_record *)(Cmap + 1);+ kbts__encoding_record *Record = &Records[Index];++ kbts__cmap_subtable_pointer Result;+ Result.PlatformId = Record->PlatformId;+ Result.EncodingId = Record->EncodingId;+ Result.Subtable = KBTS__POINTER_OFFSET(kbts_u16, Cmap, Record->SubtableOffset);++ return Result;+}++static kbts__sequence *kbts__GetSequence(kbts__multiple_substitution *Subst, kbts_un Index)+{+ kbts_u16 *Offsets = (kbts_u16 *)(Subst + 1);+ kbts__sequence *Result = KBTS__POINTER_OFFSET(kbts__sequence, Subst, Offsets[Index]);+ return Result;+}++static kbts__alternate_set *kbts__GetAlternateSet(kbts__alternate_substitution *Subst, kbts_un Index)+{+ kbts_u16 *Offsets = (kbts_u16 *)(Subst + 1);+ kbts__alternate_set *Result = KBTS__POINTER_OFFSET(kbts__alternate_set, Subst, Offsets[Index]);+ return Result;+}++static kbts__ligature_set *kbts__GetLigatureSet(kbts__ligature_substitution *Subst, kbts_un Index)+{+ kbts_u16 *Offsets = (kbts_u16 *)(Subst + 1);+ kbts__ligature_set *Result = KBTS__POINTER_OFFSET(kbts__ligature_set, Subst, Offsets[Index]);+ return Result;+}++static kbts__ligature *kbts__GetLigature(kbts__ligature_set *Set, kbts_un Index)+{+ kbts_u16 *Offsets = (kbts_u16 *)(Set + 1);+ kbts__ligature *Result = KBTS__POINTER_OFFSET(kbts__ligature, Set, Offsets[Index]);+ return Result;+}++static kbts__mark_record *kbts__GetMarkRecord(kbts__mark_array *Array, kbts_un Index)+{+ kbts__mark_record *Records = KBTS__POINTER_AFTER(kbts__mark_record, Array);+ kbts__mark_record *Result = &Records[Index];+ return Result;+}++static kbts__ligature_attach *kbts__GetLigatureAttach(kbts__ligature_array *Array, kbts_un Index)+{+ kbts_u16 *Offsets = KBTS__POINTER_AFTER(kbts_u16, Array);+ kbts__ligature_attach *Result = KBTS__POINTER_OFFSET(kbts__ligature_attach, Array, Offsets[Index]);+ return Result;+}++static kbts__anchor *kbts__GetLigatureAttachAnchor(kbts__mark_to_ligature_attachment *Adjust, kbts__ligature_attach *Attach, kbts_u16 MarkClass, kbts_un ComponentIndex)+{+ kbts_u16 *Offsets = KBTS__POINTER_AFTER(kbts_u16, Attach);+ kbts_u16 Offset = Offsets[ComponentIndex * Adjust->MarkClassCount + MarkClass];++ kbts__anchor *Result = 0;+ if(Offset)+ {+ Result = KBTS__POINTER_OFFSET(kbts__anchor, Attach, Offset);+ }++ return Result;+}++typedef struct kbts__mark_info+{+ kbts__mark_array *Array;+ kbts__mark_record *Record;+ kbts__anchor *Anchor;+} kbts__mark_info;++static kbts__mark_info kbts__GetMarkInfo(void *Subtable, kbts_un SubtableOffsetToMarkArray, kbts_un CoverageIndex)+{+ kbts__mark_info Result = KBTS__ZERO;++ Result.Array = KBTS__POINTER_OFFSET(kbts__mark_array, Subtable, SubtableOffsetToMarkArray);+ Result.Record = kbts__GetMarkRecord(Result.Array, CoverageIndex);+ Result.Anchor = KBTS__POINTER_OFFSET(kbts__anchor, Result.Array, Result.Record->AnchorOffset);++ return Result;+}++//+//+//++typedef struct kbts__byteswap_context+{+ char *FileBase;+ char *FileEnd;+ kbts_u32 *Pointers;+ kbts_un PointerCapacity;+ kbts_un PointerCount;++ int Error;+} kbts__byteswap_context;++static int kbts__ByteSwapArray16Context(kbts_u16 *Array, kbts_un Count, kbts__byteswap_context *Context)+{+ int Result = kbts__ByteSwapArray16(Array, Count, Context->FileEnd);+ Context->Error |= !Result;+ return Result;+}++static int kbts__ByteSwapArray32Context(kbts_u32 *Array, kbts_un Count, kbts__byteswap_context *Context)+{+ int Result = kbts__ByteSwapArray32(Array, Count, Context->FileEnd);+ Context->Error |= !Result;+ return Result;+}++typedef struct kbts__cover_glyph_result+{+ int Valid;+ kbts_u32 Index;+} kbts__cover_glyph_result;++static int kbts__LookupBeginsWithCoverage(kbts_shaping_table ShapingTable, kbts_u16 LookupType, kbts_u16 Format)+{+ int Result = 0;+ if(ShapingTable == KBTS_SHAPING_TABLE_GSUB)+ {+ Result = (LookupType != 7) && (Format != 3);+ }+ else+ {+ Result = (LookupType != 9) && (Format != 3);+ }+ return Result;+}++// Except for lookup tables 5.3, 6.3 and 7, all tables begin with (kbts_u16 Format, kbts_u16 CoverageOffset).+KBTS_INLINE int kbts__GsubLookupBeginsWithCoverage(kbts_u16 LookupType, kbts_u16 Format)+{+ int Result = kbts__LookupBeginsWithCoverage(KBTS_SHAPING_TABLE_GSUB, LookupType, Format);+ return Result;+}++KBTS_INLINE int kbts__GposLookupBeginsWithCoverage(kbts_u16 LookupType, kbts_u16 Format)+{+ int Result = kbts__LookupBeginsWithCoverage(KBTS_SHAPING_TABLE_GPOS, LookupType, Format);+ return Result;+}++static int kbts__AlreadyVisited(kbts__byteswap_context *Context, void *Pointer)+{+ int Result = !Pointer || Context->Error;++ if(!Result)+ {+ kbts_u32 *Pointers = Context->Pointers;+ kbts_u32 Pointer32 = KBTS__POINTER_DIFF32(Pointer, Context->FileBase);++ kbts_un Index = 0;+ if(Context->PointerCount)+ {+ kbts_un PointerCount = Context->PointerCount;+ if(PointerCount)+ {+ while(PointerCount > 1)+ {+ kbts_un HalfCount = PointerCount / 2;+ Index = (Pointers[Index + HalfCount - 1] < Pointer32) ? (Index + HalfCount) : Index;+ PointerCount -= HalfCount;+ }+ Result = (Pointer32 == Pointers[Index]);+ }+ }++ if(!Result && (Context->PointerCount < Context->PointerCapacity))+ {+ while((Index < Context->PointerCount) && (Pointers[Index] < Pointer32)) ++Index;++ for(kbts_un GrowIndex = Context->PointerCount; GrowIndex > Index; --GrowIndex)+ {+ Pointers[GrowIndex] = Pointers[GrowIndex - 1];+ }+ Pointers[Index] = Pointer32;+ Context->PointerCount += 1;+ }+ }++ return Result;+}++static void kbts__ByteSwapFeature(kbts__byteswap_context *Context, kbts__feature *Feature)+{+ if(!kbts__AlreadyVisited(Context, Feature))+ {+ kbts_u16 *LookupIndices = KBTS__POINTER_AFTER(kbts_u16, Feature);+ Context->Error |= !kbts__ByteSwapArray16(&Feature->FeatureParamsOffset, 2, Context->FileEnd);+ Context->Error |= !kbts__ByteSwapArray16(LookupIndices, Feature->LookupIndexCount, Context->FileEnd);++ // We require lookup indices to be sorted per feature for the lookup application order to match Harfbuzz.+ // Lookup indices are _typically_ sorted per feature, but we can't assume it is always the case.+ kbts_un LookupIndexCount = Feature->LookupIndexCount;+ KBTS__FOR(Iter, 0, LookupIndexCount)+ {+ KBTS__FOR(IndexIndex, 1, LookupIndexCount)+ {+ kbts_u16 Left = LookupIndices[IndexIndex - 1];+ kbts_u16 Right = LookupIndices[IndexIndex];++ if(Left > Right)+ {+ LookupIndices[IndexIndex - 1] = Right;+ LookupIndices[IndexIndex] = Left;+ }+ }+ }+ }++# ifdef KBTS_DUMP+ kbts_u16 *LookupIndices = KBTS__POINTER_AFTER(kbts_u16, Feature);+ KBTS__FOR(LookupIndexIndex, 0, Feature->LookupIndexCount)+ {+ KBTS_DUMPF(" Lookup index %u\n", LookupIndices[LookupIndexIndex]);+ }+# endif+}++static void kbts__ByteSwapGsubGposCommon(kbts__byteswap_context *Context, kbts__gsub_gpos *Header)+{+ kbts__ByteSwapArray16Context(&Header->Major, 5, Context);++ if(Header->Minor == 1)+ {+ Header->FeatureVariationsOffset = kbts__ByteSwap32(Header->FeatureVariationsOffset);+ }++ kbts__script_list *ScriptList = KBTS__POINTER_OFFSET(kbts__script_list, Header, Header->ScriptListOffset);+ if(!kbts__AlreadyVisited(Context, ScriptList))+ {+ ScriptList->Count = kbts__ByteSwap16(ScriptList->Count);++ kbts__script_record *ScriptRecords = KBTS__POINTER_AFTER(kbts__script_record, ScriptList);+ KBTS__FOR(It, 0, ScriptList->Count)+ {+ kbts__script_record *Record = &ScriptRecords[It];++ Record->Offset = kbts__ByteSwap16(Record->Offset);++ KBTS_DUMPF("Script %.4s\n", (char *)&Record->Tag);++ kbts__ot_script *Script = KBTS__POINTER_OFFSET(kbts__ot_script, ScriptList, Record->Offset);+ if(!kbts__AlreadyVisited(Context, Script))+ {+ Script->DefaultLangsysOffset = kbts__ByteSwap16(Script->DefaultLangsysOffset);+ Script->Count = kbts__ByteSwap16(Script->Count);++ kbts__langsys *DefaultLangsys = kbts__GetDefaultLangsys(Script);++ if(DefaultLangsys && !kbts__AlreadyVisited(Context, DefaultLangsys))+ {+ kbts__ByteSwapArray16Context(&DefaultLangsys->LookupOrderOffset, 3, Context);+ kbts__ByteSwapArray16Context(KBTS__POINTER_AFTER(kbts_u16, DefaultLangsys), DefaultLangsys->FeatureIndexCount, Context);+ }++ kbts__langsys_record *LangsysRecords = KBTS__POINTER_AFTER(kbts__langsys_record, Script);+ KBTS__FOR(LangsysIndex, 0, Script->Count)+ {+ kbts__langsys_record *LangsysRecord = &LangsysRecords[LangsysIndex];++ LangsysRecord->Offset = kbts__ByteSwap16(LangsysRecord->Offset);++ kbts__langsys *Langsys = KBTS__POINTER_OFFSET(kbts__langsys, Script, LangsysRecord->Offset);+ if(!kbts__AlreadyVisited(Context, Langsys))+ {+ kbts__ByteSwapArray16Context(&Langsys->LookupOrderOffset, 3, Context);+ kbts__ByteSwapArray16Context(KBTS__POINTER_AFTER(kbts_u16, Langsys), Langsys->FeatureIndexCount, Context);+ }+ }++# ifdef KBTS_DUMP+ if(DefaultLangsys)+ {+ KBTS_DUMPF(" Default langsys @ %zu\n", (char *)DefaultLangsys - Context->FileBase);+ KBTS_DUMPF(" Lookup order offset %u\n", DefaultLangsys->LookupOrderOffset);+ KBTS_DUMPF(" Required feature %u\n", DefaultLangsys->RequiredFeatureIndex);+ kbts_u16 *FeatureIndices = KBTS__POINTER_AFTER(kbts_u16, DefaultLangsys);+ KBTS__FOR(FeatureIndexIndex, 0, DefaultLangsys->FeatureIndexCount)+ {+ KBTS_DUMPF(" Feature %u\n", FeatureIndices[FeatureIndexIndex]);+ }+ }++ KBTS__FOR(LangsysIndex, 0, Script->Count)+ {+ kbts__langsys_record *LangsysRecord = &LangsysRecords[LangsysIndex];+ kbts__langsys *Langsys = KBTS__POINTER_OFFSET(kbts__langsys, Script, LangsysRecord->Offset);+ KBTS_DUMPF(" Langsys %.4s @ %zu\n", (char *)&LangsysRecord->Tag, (char *)Script + LangsysRecord->Offset - Context->FileBase);+ KBTS_DUMPF(" Lookup order offset %u\n"+ " Required feature %u\n",+ Langsys->LookupOrderOffset, Langsys->RequiredFeatureIndex);+ kbts_u16 *FeatureIndices = KBTS__POINTER_AFTER(kbts_u16, Langsys);+ KBTS__FOR(FeatureIndexIndex, 0, Langsys->FeatureIndexCount)+ {+ KBTS_DUMPF(" Feature %u\n", FeatureIndices[FeatureIndexIndex]);+ }+ }+# endif+ }+ }++ // @Incomplete+ if((Header->Minor == 1) && Header->FeatureVariationsOffset)+ {+ kbts__feature_variations *FeatureVariations = KBTS__POINTER_OFFSET(kbts__feature_variations, Header, Header->FeatureVariationsOffset);++ if(!kbts__AlreadyVisited(Context, FeatureVariations))+ {+ kbts__ByteSwapArray16Context(&FeatureVariations->Major, 2, Context);+ FeatureVariations->RecordCount = kbts__ByteSwap32(FeatureVariations->RecordCount);++ kbts__feature_variation_record *Records = KBTS__POINTER_AFTER(kbts__feature_variation_record, FeatureVariations);+ KBTS__FOR(VariationIndex, 0, FeatureVariations->RecordCount)+ {+ kbts__feature_variation_record *Record = &Records[VariationIndex];++ kbts__ByteSwapArray32Context(&Record->ConditionSetOffset, 2, Context);++ kbts__condition_set *Set = KBTS__POINTER_OFFSET(kbts__condition_set, FeatureVariations, Record->ConditionSetOffset);++ if(!kbts__AlreadyVisited(Context, Set))+ {+ Set->Count = kbts__ByteSwap16(Set->Count);++ kbts_u32 *ConditionOffsets = KBTS__POINTER_AFTER(kbts_u32, Set);+ kbts__ByteSwapArray32Context(ConditionOffsets, Set->Count, Context);++ KBTS__FOR(ConditionIndex, 0, Set->Count)+ {+ kbts__condition_1 *Condition = KBTS__POINTER_OFFSET(kbts__condition_1, Set, ConditionOffsets[ConditionIndex]);++ if(!kbts__AlreadyVisited(Context, Condition))+ {+ kbts__ByteSwapArray16Context(&Condition->Format, 4, Context);+ }+ }++ // @Incomplete+ kbts__feature_table_substitution *FeatureSubst = KBTS__POINTER_OFFSET(kbts__feature_table_substitution, FeatureVariations, Record->FeatureTableSubstitutionOffset);++ if(!kbts__AlreadyVisited(Context, FeatureSubst))+ {+ kbts__ByteSwapArray16Context(&FeatureSubst->Major, 3, Context);++ kbts__feature_table_substitution_record *SubstRecords = KBTS__POINTER_AFTER(kbts__feature_table_substitution_record, FeatureSubst);+ KBTS__FOR(SubstRecordIndex, 0, FeatureSubst->Count)+ {+ kbts__feature_table_substitution_record *SubstRecord = &SubstRecords[SubstRecordIndex];+ SubstRecord->FeatureIndex = kbts__ByteSwap16(SubstRecord->FeatureIndex);+ SubstRecord->AlternateFeatureOffset = kbts__ByteSwap32(SubstRecord->AlternateFeatureOffset);++ kbts__feature *Feature = KBTS__POINTER_OFFSET(kbts__feature, FeatureSubst, SubstRecord->AlternateFeatureOffset);+ kbts__ByteSwapFeature(Context, Feature);+ }+ }+ }+ }+ }+ }+ }++ kbts__feature_list *FeatureList = KBTS__POINTER_OFFSET(kbts__feature_list, Header, Header->FeatureListOffset);+ if(!kbts__AlreadyVisited(Context, FeatureList))+ {+ FeatureList->Count = kbts__ByteSwap16(FeatureList->Count);+ kbts__feature_record *FeatureRecords = KBTS__POINTER_AFTER(kbts__feature_record, FeatureList);+ KBTS__FOR(FeatureRecordIndex, 0, FeatureList->Count)+ {+ kbts__feature_record *FeatureRecord = &FeatureRecords[FeatureRecordIndex];++ KBTS_DUMPF("Feature %llu %.4s\n", FeatureRecordIndex, (char *)&FeatureRecord->Tag);++ if(!kbts__AlreadyVisited(Context, FeatureRecord))+ {+ FeatureRecord->Offset = kbts__ByteSwap16(FeatureRecord->Offset);++ kbts__feature *Feature = KBTS__POINTER_OFFSET(kbts__feature, FeatureList, FeatureRecord->Offset);+ kbts__ByteSwapFeature(Context, Feature);+ }+ }+ }+}++static int kbts__ByteSwapLookup(kbts__byteswap_context *Context, kbts__lookup *Lookup)+{+ int Result = 0;++ if(!kbts__AlreadyVisited(Context, Lookup))+ {+ Result = 1;++ kbts__ByteSwapArray16Context(&Lookup->Type, 3, Context);+ kbts_u16 *SubtableOffsets = KBTS__POINTER_AFTER(kbts_u16, Lookup);++ kbts_un U16Count = Lookup->SubtableCount;+ if(Lookup->Flag & KBTS__LOOKUP_FLAG_USE_MARK_FILTERING_SET)+ {+ U16Count += 1;+ }+ kbts__ByteSwapArray16Context(SubtableOffsets, U16Count, Context);+ }++ return Result;+}++static void kbts__ByteSwapCoverage(kbts__byteswap_context *Context, kbts__coverage *Coverage)+{+ if(!kbts__AlreadyVisited(Context, Coverage))+ {+ kbts__ByteSwapArray16Context(&Coverage->Format, 2, Context);++ kbts_un U16Count = 0;+ if(Coverage->Format == 1)+ {+ U16Count = Coverage->Count;+ }+ else if(Coverage->Format == 2)+ {+ U16Count = Coverage->Count * 3;+ }++ kbts__ByteSwapArray16Context(KBTS__POINTER_AFTER(kbts_u16, Coverage), U16Count, Context);+ }+}++static void kbts__ByteSwapAnchor(kbts__byteswap_context *Context, kbts__anchor *Anchor)+{+ if(!kbts__AlreadyVisited(Context, Anchor))+ {+ Anchor->Format = kbts__ByteSwap16(Anchor->Format);++ kbts_un U16Count = 2;+ if(Anchor->Format == 2)+ {+ U16Count = 3;+ }+ else if(Anchor->Format == 3)+ {+ U16Count = 4;+ }++ kbts__ByteSwapArray16Context((kbts_u16 *)&Anchor->X, U16Count, Context);+ }+}++static void kbts__ByteSwapBaseArray(kbts__byteswap_context *Context, kbts_u16 MarkClassCount, kbts__base_array *Array)+{+ if(!kbts__AlreadyVisited(Context, Array))+ {+ Array->BaseCount = kbts__ByteSwap16(Array->BaseCount);++ kbts_u16 *BaseAnchorOffsets = KBTS__POINTER_AFTER(kbts_u16, Array);+ kbts__ByteSwapArray16Context(BaseAnchorOffsets, Array->BaseCount * MarkClassCount, Context);++ KBTS__FOR(OffsetIndex, 0, (kbts_un)Array->BaseCount * MarkClassCount)+ {+ kbts_u16 Offset = BaseAnchorOffsets[OffsetIndex];++ if(Offset)+ {+ kbts__ByteSwapAnchor(Context, KBTS__POINTER_OFFSET(kbts__anchor, Array, Offset));+ }+ }+ }+}++static void kbts__ByteSwapDevice(kbts__byteswap_context *Context, kbts__device *Device)+{+ if(!kbts__AlreadyVisited(Context, Device))+ {+ kbts__ByteSwapArray16Context(&Device->U.Device.StartSize, 3, Context);++ if(Device->DeltaFormat <= 3)+ {+ // @Incomplete+ }+ }+}++static kbts__unpacked_value_record kbts_ByteSwapValueRecord(kbts__byteswap_context *Context, void *Parent, kbts_u16 ValueFormat, kbts_u16 *Record)+{+ kbts__unpacked_value_record Result = KBTS__ZERO;++ if(ValueFormat)+ {+ kbts_un U16Count = kbts__PopCount32(ValueFormat);++ kbts__ByteSwapArray16Context(Record, U16Count, Context);++ Result = kbts__UnpackValueRecord(Parent, ValueFormat, Record);++ kbts__ByteSwapDevice(Context, Result.PlacementXDevice);+ kbts__ByteSwapDevice(Context, Result.PlacementYDevice);+ kbts__ByteSwapDevice(Context, Result.AdvanceXDevice);+ kbts__ByteSwapDevice(Context, Result.AdvanceYDevice);+ }++ return Result;+}++static void kbts__ByteSwapMarkArray(kbts__byteswap_context *Context, kbts__mark_array *MarkArray)+{+ if(!kbts__AlreadyVisited(Context, MarkArray))+ {+ MarkArray->Count = kbts__ByteSwap16(MarkArray->Count);+ kbts__ByteSwapArray16Context(KBTS__POINTER_AFTER(kbts_u16, MarkArray), MarkArray->Count * 2, Context);++ kbts__mark_record *MarkRecords = KBTS__POINTER_AFTER(kbts__mark_record, MarkArray);+ KBTS__FOR(MarkRecordIndex, 0, MarkArray->Count)+ {+ kbts__mark_record *MarkRecord = &MarkRecords[MarkRecordIndex];++ kbts__ByteSwapAnchor(Context, KBTS__POINTER_OFFSET(kbts__anchor, MarkArray, MarkRecord->AnchorOffset));+ }+ }+}++static void kbts__ByteSwapChainedSequenceRuleSet(kbts__byteswap_context *Context, kbts__chained_sequence_rule_set *Set)+{+ if(Set && !kbts__AlreadyVisited(Context, Set))+ {+ Set->Count = kbts__ByteSwap16(Set->Count);+ kbts__ByteSwapArray16Context(KBTS__POINTER_AFTER(kbts_u16, Set), Set->Count, Context);++ KBTS__FOR(RuleIndex, 0, Set->Count)+ {+ kbts__chained_sequence_rule *Rule = kbts__GetChainedSequenceRule(Set, RuleIndex);++ if(!kbts__AlreadyVisited(Context, Rule))+ {+ kbts__unpacked_chained_sequence_rule Unpacked = kbts__UnpackChainedSequenceRule(Rule, 1);++ kbts_un U16Count = Unpacked.BacktrackCount + Unpacked.InputCount + Unpacked.LookaheadCount + Unpacked.RecordCount * 2 + 3;+ kbts__ByteSwapArray16Context(&Rule->BacktrackGlyphCount, U16Count, Context);+ }+ }+ }+}++#ifdef KBTS_DUMP+static void kbts__DumpClassDefinition(kbts_u16 *Base)+{+ if(*Base == 1)+ {+ kbts__class_definition_1 *ClassDef = (kbts__class_definition_1 *)Base;+ kbts_u16 *ClassValues = KBTS__POINTER_AFTER(kbts_u16, ClassDef);+ KBTS__FOR(GlyphIndex, 0, ClassDef->GlyphCount)+ {+ KBTS_DUMPF("%llx -> %u\n", ClassDef->StartGlyphId + GlyphIndex, ClassValues[GlyphIndex]);+ }+ }+ else if(*Base == 2)+ {+ kbts__class_definition_2 *ClassDef = (kbts__class_definition_2 *)Base;+ kbts__class_range_record *Ranges = KBTS__POINTER_AFTER(kbts__class_range_record, ClassDef);+ KBTS__FOR(RangeIndex, 0, ClassDef->Count)+ {+ kbts__class_range_record *Range = &Ranges[RangeIndex];++ KBTS_DUMPF("[%x..%x] -> %u\n", Range->StartGlyphId, Range->EndGlyphId, Range->Class);+ }+ }+}+#endif++static void kbts__ByteSwapClassDefinition(kbts__byteswap_context *Context, kbts_u16 *Base)+{+ if(!kbts__AlreadyVisited(Context, Base))+ {+ *Base = kbts__ByteSwap16(*Base);++ if(*Base == 1)+ {+ kbts__class_definition_1 *ClassDef = (kbts__class_definition_1 *)Base;+ kbts__ByteSwapArray16Context(&ClassDef->StartGlyphId, 2, Context);+ kbts__ByteSwapArray16Context(KBTS__POINTER_AFTER(kbts_u16, ClassDef), ClassDef->GlyphCount, Context);+ }+ else if(*Base == 2)+ {+ kbts__class_definition_2 *ClassDef = (kbts__class_definition_2 *)Base;+ ClassDef->Count = kbts__ByteSwap16(ClassDef->Count);++ kbts__ByteSwapArray16Context(KBTS__POINTER_AFTER(kbts_u16, ClassDef), ClassDef->Count * 3, Context);+ }+ }+}++typedef struct kbts__glyph_class_from_table_result+{+ int Found;+ kbts_u16 Class;+} kbts__glyph_class_from_table_result;++static kbts__glyph_class_from_table_result kbts__GlyphClassFromTable(kbts_u16 *ClassDefinitionBase, kbts_un Id)+{+ kbts__glyph_class_from_table_result Result = KBTS__ZERO;++ // From the Microsoft docs:+ // There is one offset to a ChainedClassSequenceRuleSet subtable for each class defined in the input sequence+ // class definition table. The offsets are listed in class value order.+ // This means that we do not actually care what the class _values_ are. We only care about the classes' relative+ // values.+ // Also from the Microsoft docs, about class definition tables:+ // A class definition table (ClassDef) assigns glyphs into classes, beginning with Class 1, then Class 2, and so+ // on. All glyphs not assigned to a class fall into Class 0.+ // So, we should be able to pretty reliably just subtract 1 from the class to get.++ if(*ClassDefinitionBase == 1)+ {+ kbts__class_definition_1 *ClassDef = (kbts__class_definition_1 *)ClassDefinitionBase;+ kbts_u16 *GlyphClasses = KBTS__POINTER_AFTER(kbts_u16, ClassDef);++ kbts_un Offset = Id - ClassDef->StartGlyphId;+ if(Offset < ClassDef->GlyphCount)+ {+ Result.Class = GlyphClasses[Offset];+ Result.Found = 1;+ }+ }+ else if(*ClassDefinitionBase == 2)+ {+ kbts__class_definition_2 *ClassDef = (kbts__class_definition_2 *)ClassDefinitionBase;+ kbts__class_range_record *Ranges = KBTS__POINTER_AFTER(kbts__class_range_record, ClassDef);++ kbts_un RangeCount = ClassDef->Count;+ if(RangeCount)+ {+ while(RangeCount > 1)+ {+ kbts_un HalfCount = RangeCount / 2;+ Ranges = (Ranges[HalfCount - 1].EndGlyphId < Id) ? (Ranges + HalfCount) : Ranges;+ RangeCount -= HalfCount;+ }+ if((Id >= Ranges->StartGlyphId) && (Id <= Ranges->EndGlyphId))+ {+ Result.Class = Ranges->Class;+ Result.Found = 1;+ }+ }+ }++ return Result;+}++static kbts__cover_glyph_result kbts__CoverGlyph(kbts__coverage *Coverage, kbts_u32 GlyphId)+{+ KBTS_INSTRUMENT_FUNCTION_BEGIN;+ kbts__cover_glyph_result Result = KBTS__ZERO;+ kbts_un Count = Coverage->Count;++ if(Count)+ {+ if(Coverage->Format == 1)+ {+ kbts_u16 *GlyphIds = KBTS__POINTER_AFTER(kbts_u16, Coverage);++ while(Count > 1)+ {+ kbts_un HalfCount = Count / 2;+ GlyphIds = (GlyphIds[HalfCount - 1] < GlyphId) ? (GlyphIds + HalfCount) : GlyphIds;+ Count -= HalfCount;+ }++ if(GlyphId == *GlyphIds)+ {+ Result.Valid = 1;+ Result.Index = (kbts_u32)(GlyphIds - KBTS__POINTER_AFTER(kbts_u16, Coverage));+ }+ }+ else if(Coverage->Format == 2)+ {+ kbts__range_record *Ranges = KBTS__POINTER_AFTER(kbts__range_record, Coverage);++ while(Count > 1)+ {+ kbts_un HalfCount = Count / 2;+ Ranges = (Ranges[HalfCount - 1].EndGlyphId < GlyphId) ? (Ranges + HalfCount) : Ranges;+ Count -= HalfCount;+ }+ if((GlyphId >= Ranges->StartGlyphId) && (GlyphId <= Ranges->EndGlyphId))+ {+ Result.Valid = 1;+ Result.Index = Ranges->StartCoverageIndex + GlyphId - Ranges->StartGlyphId;+ }+ }+ }++ KBTS_INSTRUMENT_FUNCTION_END;+ return Result;+}++static void kbts__ByteSwapSequenceContextSubtable(kbts__byteswap_context *Context, kbts_u16 *Base)+{+ if(Base[0] == 1)+ {+ kbts__sequence_context_1 *Subst = (kbts__sequence_context_1 *)Base;+ Subst->SeqRuleSetCount = kbts__ByteSwap16(Subst->SeqRuleSetCount);+ kbts__ByteSwapArray16Context(KBTS__POINTER_AFTER(kbts_u16, Subst), Subst->SeqRuleSetCount, Context);++ KBTS__FOR(SetIndex, 0, Subst->SeqRuleSetCount)+ {+ kbts__sequence_rule_set *Set = kbts__GetSequenceRuleSet(Subst, SetIndex);++ if(Set && !kbts__AlreadyVisited(Context, Set))+ {+ Set->Count = kbts__ByteSwap16(Set->Count);+ kbts__ByteSwapArray16Context(KBTS__POINTER_AFTER(kbts_u16, Set), Set->Count, Context);++ KBTS__FOR(RuleIndex, 0, Set->Count)+ {+ kbts__sequence_rule *Rule = kbts__GetSequenceRule(Set, RuleIndex);++ if(!kbts__AlreadyVisited(Context, Rule))+ {+ kbts__ByteSwapArray16Context(&Rule->GlyphCount, 2, Context);+ kbts__ByteSwapArray16Context(KBTS__POINTER_AFTER(kbts_u16, Rule), (kbts_un)Rule->GlyphCount - 1 + (kbts_un)Rule->SequenceLookupCount * 2, Context);+ }+ }+ }+ }+ }+ else if(Base[0] == 2)+ {+ kbts__sequence_context_2 *Subst = (kbts__sequence_context_2 *)Base;+ kbts__ByteSwapArray16Context(&Subst->ClassDefOffset, 2, Context);+ kbts__ByteSwapArray16Context(KBTS__POINTER_AFTER(kbts_u16, Subst), Subst->ClassSequenceRuleSetCount, Context);++ kbts_u16 *ClassDefBase = KBTS__POINTER_OFFSET(kbts_u16, Subst, Subst->ClassDefOffset);+ kbts__ByteSwapClassDefinition(Context, ClassDefBase);++ KBTS__FOR(SetIndex, 0, Subst->ClassSequenceRuleSetCount)+ {+ kbts__class_sequence_rule_set *Set = kbts__GetClassSequenceRuleSet(Subst, SetIndex);++ if(Set && !kbts__AlreadyVisited(Context, Set))+ {+ Set->Count = kbts__ByteSwap16(Set->Count);+ kbts__ByteSwapArray16Context(KBTS__POINTER_AFTER(kbts_u16, Set), Set->Count, Context);++ KBTS__FOR(RuleIndex, 0, Set->Count)+ {+ kbts__class_sequence_rule *Rule = kbts__GetClassSequenceRule(Set, RuleIndex);++ if(!kbts__AlreadyVisited(Context, Rule))+ {+ kbts__ByteSwapArray16Context(&Rule->GlyphCount, 2, Context);+ kbts__ByteSwapArray16Context(KBTS__POINTER_AFTER(kbts_u16, Rule), Rule->GlyphCount - 1 + 2 * Rule->SequenceLookupCount, Context);+ }+ }+ }+ }++ #ifdef KBTS_DUMP+ kbts__DumpClassDefinition(ClassDefBase);+ KBTS__FOR(SetIndex, 0, Subst->ClassSequenceRuleSetCount)+ {+ kbts__class_sequence_rule_set *Set = kbts__GetClassSequenceRuleSet(Subst, SetIndex);++ if(Set)+ {+ KBTS__FOR(RuleIndex, 0, Set->Count)+ {+ kbts__class_sequence_rule *Rule = kbts__GetClassSequenceRule(Set, RuleIndex);+ kbts_u16 *InputSequence = KBTS__POINTER_AFTER(kbts_u16, Rule);+ kbts__sequence_lookup_record *Records = (kbts__sequence_lookup_record *)(InputSequence + Rule->GlyphCount - 1);+ KBTS_DUMPF("Input: [");+ KBTS__FOR(GlyphIndex, 1, Rule->GlyphCount)+ {+ KBTS_DUMPF(", %x", InputSequence[GlyphIndex - 1]);+ }+ KBTS_DUMPF("]\nRecords: [");+ KBTS__FOR(RecordIndex, 0, Rule->SequenceLookupCount)+ {+ kbts__sequence_lookup_record *Record = &Records[RecordIndex];+ if(RecordIndex) KBTS_DUMPF(", ");+ KBTS_DUMPF("%u@%u", Record->LookupListIndex, Record->SequenceIndex);+ }+ KBTS_DUMPF("]\n");+ }+ }+ }+ #endif+ }+ else if(Base[0] == 3)+ {+ kbts__sequence_context_3 *Subst = (kbts__sequence_context_3 *)Base;+ kbts__ByteSwapArray16Context(&Subst->GlyphCount, 2, Context);+ kbts__ByteSwapArray16Context(KBTS__POINTER_AFTER(kbts_u16, Subst), Subst->GlyphCount + 2 * Subst->SequenceLookupCount, Context);++ kbts_u16 *CoverageOffsets = KBTS__POINTER_AFTER(kbts_u16, Subst);+ KBTS__FOR(CoverageIndex, 0, Subst->GlyphCount)+ {+ kbts__coverage *Coverage = KBTS__POINTER_OFFSET(kbts__coverage, Subst, CoverageOffsets[CoverageIndex]);++ kbts__ByteSwapCoverage(Context, Coverage);+ }+ }+}++typedef kbts_u32 kbts__skip_flags;+enum kbts__skip_flags_enum+{+ KBTS__SKIP_FLAG_NONE,+ KBTS__SKIP_FLAG_ZWNJ = (1 << 0),+ KBTS__SKIP_FLAG_ZWJ = (1 << 1),+};+// The Harfbuzz behavior is:+// - GPOS lookups always skip ZWNJ.+// - Sequence lookups always skip ZWJ.+// - GSUB sequence lookups skip ZWNJ when requested.+// - Regular lookups skip ZWJ when requested.+#define KBTS__SKIP_FLAGS_GSUB_REGULAR(RequestedFlags) ((RequestedFlags) & KBTS__SKIP_FLAG_ZWJ)+#define KBTS__SKIP_FLAGS_GSUB_SEQUENCE(RequestedFlags) (KBTS__SKIP_FLAG_ZWJ | ((RequestedFlags) & KBTS__SKIP_FLAG_ZWNJ))+#define KBTS__SKIP_FLAGS_GPOS_REGULAR(RequestedFlags) (((RequestedFlags) & KBTS__SKIP_FLAG_ZWJ) | KBTS__SKIP_FLAG_ZWNJ)+#define KBTS__SKIP_FLAGS_GPOS_SEQUENCE(RequestedFlags) (KBTS__SKIP_FLAG_ZWJ | KBTS__SKIP_FLAG_ZWNJ)++static kbts__skip_flags kbts__SkipFlags(kbts__feature_id FeatureId, kbts_shaper Shaper)+{+ kbts__skip_flags Result = 0;+ switch(FeatureId)+ {+ case KBTS__FEATURE_ID_nukt:+ case KBTS__FEATURE_ID_akhn:+ case KBTS__FEATURE_ID_rphf:+ case KBTS__FEATURE_ID_rkrf:+ case KBTS__FEATURE_ID_pref:+ case KBTS__FEATURE_ID_blwf:+ case KBTS__FEATURE_ID_abvf:+ case KBTS__FEATURE_ID_half:+ case KBTS__FEATURE_ID_pstf:+ case KBTS__FEATURE_ID_vatu:+ case KBTS__FEATURE_ID_cjct:+ case KBTS__FEATURE_ID_pres:+ case KBTS__FEATURE_ID_abvs:+ case KBTS__FEATURE_ID_blws:+ case KBTS__FEATURE_ID_psts:+ case KBTS__FEATURE_ID_haln:+ case KBTS__FEATURE_ID_cfar:+ if(Shaper == KBTS_SHAPER_USE)+ {+ Result = KBTS__SKIP_FLAG_ZWNJ;+ }+ else if((Shaper == KBTS_SHAPER_INDIC) ||+ (Shaper == KBTS_SHAPER_KHMER))+ {+ Result = 0;+ }+ else+ {+ Result = KBTS__SKIP_FLAG_ZWNJ | KBTS__SKIP_FLAG_ZWJ;+ }+ break;++ case KBTS__FEATURE_ID_init:+ if (Shaper == KBTS_SHAPER_INDIC) {Result = 0;}+ else if(Shaper == KBTS_SHAPER_ARABIC) {Result = KBTS__SKIP_FLAG_ZWNJ;}+ else {Result = KBTS__SKIP_FLAG_ZWNJ | KBTS__SKIP_FLAG_ZWJ;}+ break;++ case KBTS__FEATURE_ID_ccmp:+ case KBTS__FEATURE_ID_locl:+ case KBTS__FEATURE_ID_isol:+ case KBTS__FEATURE_ID_fina:+ case KBTS__FEATURE_ID_fin2:+ case KBTS__FEATURE_ID_fin3:+ case KBTS__FEATURE_ID_medi:+ case KBTS__FEATURE_ID_med2:+ case KBTS__FEATURE_ID_calt:+ case KBTS__FEATURE_ID_liga:+ case KBTS__FEATURE_ID_clig:+ case KBTS__FEATURE_ID_rlig:+ case KBTS__FEATURE_ID_mset:+ Result = (Shaper == KBTS_SHAPER_ARABIC) ? KBTS__SKIP_FLAG_ZWNJ : KBTS__SKIP_FLAG_ZWNJ | KBTS__SKIP_FLAG_ZWJ;+ break;++ case KBTS__FEATURE_ID_mark:+ case KBTS__FEATURE_ID_mkmk:+ Result = 0;+ break;++ default:+ Result = KBTS__SKIP_FLAG_ZWNJ | KBTS__SKIP_FLAG_ZWJ;+ break;+ }+ return Result;+}++static int kbts__GlyphPassesLookupFilter(kbts_glyph *Glyph, kbts__unpacked_lookup *Lookup)+{+ int Result = 1;+ kbts_u16 Class = Glyph->Classes.Class;++ if(Class && (Lookup->Flags & (1 << Class)))+ {+ Result = 0;+ }++ if(Result && (Class == KBTS__GLYPH_CLASS_MARK))+ {+ if(Lookup->Flags & KBTS__LOOKUP_FLAG_MARK_ATTACHMENT_CLASS_FILTER)+ {+ kbts_u32 DesiredMarkAttachmentClass = Lookup->Flags >> 8;++ if(Glyph->Classes.MarkAttachmentClass != DesiredMarkAttachmentClass)+ {+ Result = 0;+ }+ }++ if(Result && Lookup->MarkFilteringSet)+ {+ // @Speed: We may want to save the result of the last mark filtering test on the glyph itself.+ kbts__cover_glyph_result Cover = kbts__CoverGlyph(Lookup->MarkFilteringSet, Glyph->Id);+ if(!Cover.Valid)+ {+ Result = 0;+ }+ }+ }++ return Result;+}++static int kbts__SkipGlyph(kbts_glyph *Glyph, kbts__unpacked_lookup *Lookup, kbts__skip_flags SkipFlags, kbts_u32 SkipUnicodeFlags)+{+ int Result = (Glyph->UnicodeFlags & SkipUnicodeFlags) ||+ ((SkipFlags & KBTS__SKIP_FLAG_ZWNJ) && (Glyph->Codepoint == 0x200C)) ||+ ((SkipFlags & KBTS__SKIP_FLAG_ZWJ) && (Glyph->Codepoint == 0x200D)) ||+ !kbts__GlyphPassesLookupFilter(Glyph, Lookup);+ return Result;+}++static int kbts__GlyphIsValid(kbts_glyph_storage *Storage, kbts_glyph *Glyph)+{+ int Result = Glyph != &Storage->GlyphSentinel;+ return Result;+}++typedef struct kbts__matrix_index+{+ kbts_un WordIndex;+ kbts_un BitIndex;+} kbts__matrix_index;++static kbts__matrix_index kbts__GlyphLookupMatrixIndex(kbts_un LookupIndex, kbts_un GlyphIndex, kbts_un GlyphCount)+{+ kbts_un FlatIndex = LookupIndex * GlyphCount + GlyphIndex;++ kbts__matrix_index Result = KBTS__ZERO;+ Result.WordIndex = FlatIndex / 32;+ Result.BitIndex = GlyphIndex % 32;++ return Result;+}++static kbts__matrix_index kbts__GlyphLookupSubtableMatrixIndex(kbts_un SubtableIndex, kbts_un SubtableCount, kbts_un GlyphIndex)+{+ // Since we try many subtables in a row against the same glyphs, the rows are glyph-wise and the columns subtable-wise.+ kbts_un FlatIndex = GlyphIndex * SubtableCount + SubtableIndex;++ kbts__matrix_index Result = KBTS__ZERO;+ Result.WordIndex = FlatIndex / 32;+ Result.BitIndex = FlatIndex % 32;+ return Result;+}++static int kbts__GlyphsIncludedInLookupSubtable(kbts_glyph_storage *Storage, kbts_font *Font, int Gpos, kbts__unpacked_lookup *Lookup, kbts_un LookupIndex, kbts_un SubtableIndex, kbts_glyph *AtGlyph, kbts__skip_flags SkipFlags, kbts_unicode_flags SkipUnicodeFlags)+{+ if(Font->Blob->GlyphLookupSubtableMatrixOffsetFromStartOfFile)+ {+ kbts_u32 *GlyphLookupSubtableMatrix = KBTS__POINTER_OFFSET(kbts_u32, Font->Blob, Font->Blob->GlyphLookupSubtableMatrixOffsetFromStartOfFile);+ kbts_u32 *LookupSubtableIndexOffsets = KBTS__POINTER_OFFSET(kbts_u32, Font->Blob, Font->Blob->LookupSubtableIndexOffsetsOffsetFromStartOfFile);+ kbts_lookup_subtable_info *SubtableInfos = KBTS__POINTER_OFFSET(kbts_lookup_subtable_info, Font->Blob, Font->Blob->SubtableInfosOffsetFromStartOfFile);+ kbts_un GlyphCount = Font->Blob->GlyphCount;+ kbts_un SubtableCount = Font->Blob->LookupSubtableCount;++ kbts_un FlatLookupIndex = (Gpos ? Font->Blob->GposLookupIndexOffset : 0) + LookupIndex;+ kbts_un FlatSubtableIndex = LookupSubtableIndexOffsets[FlatLookupIndex] + SubtableIndex;+ kbts_lookup_subtable_info *Info = &SubtableInfos[FlatSubtableIndex];+ kbts_un MinimumBacktrack = (Info->MinimumBacktrackPlusOne) ? Info->MinimumBacktrackPlusOne - 1 : 0;+ kbts_un MinimumFollowup = (Info->MinimumFollowupPlusOne) ? Info->MinimumFollowupPlusOne - 1 : 0;++ { // Check the current glyph.+ kbts_un Id = AtGlyph->Id;+ kbts__matrix_index MatrixIndex = kbts__GlyphLookupSubtableMatrixIndex(FlatSubtableIndex, SubtableCount, Id);+ if(Id >= GlyphCount)+ {+ return 1;+ }+ else if(!(GlyphLookupSubtableMatrix[MatrixIndex.WordIndex] & (1 << MatrixIndex.BitIndex)))+ {+ return 0;+ }+ }++ {+ kbts_un BacktrackCounter = 0;+ kbts_glyph *BacktrackGlyph = AtGlyph->Prev;+ while(kbts__GlyphIsValid(Storage, BacktrackGlyph) &&+ (BacktrackCounter < MinimumBacktrack))+ {+ kbts__matrix_index MatrixIndex = kbts__GlyphLookupSubtableMatrixIndex(FlatSubtableIndex, SubtableCount, BacktrackGlyph->Id);++ if((BacktrackGlyph->Id >= GlyphCount) ||+ kbts__SkipGlyph(BacktrackGlyph, Lookup, SkipFlags, SkipUnicodeFlags) ||+ GlyphLookupSubtableMatrix[MatrixIndex.WordIndex] & (1 << MatrixIndex.BitIndex))+ {+ BacktrackCounter += 1;+ }+ else+ {+ return 0;+ }++ BacktrackGlyph = BacktrackGlyph->Prev;+ }++ if(BacktrackCounter < MinimumBacktrack)+ {+ return 0;+ }+ }++ {+ kbts_un LookaheadCounter = 0;+ kbts_glyph *LookaheadGlyph = AtGlyph->Next;+ while(kbts__GlyphIsValid(Storage, LookaheadGlyph) && (LookaheadCounter < MinimumFollowup))+ {+ kbts__matrix_index MatrixIndex = kbts__GlyphLookupSubtableMatrixIndex(FlatSubtableIndex, SubtableCount, LookaheadGlyph->Id);++ if((LookaheadGlyph->Id >= GlyphCount) ||+ kbts__SkipGlyph(LookaheadGlyph, Lookup, SkipFlags, SkipUnicodeFlags) ||+ GlyphLookupSubtableMatrix[MatrixIndex.WordIndex] & (1 << MatrixIndex.BitIndex))+ {+ LookaheadCounter += 1;+ }+ else+ {+ return 0;+ }++ LookaheadGlyph = LookaheadGlyph->Next;+ }++ if(LookaheadCounter < MinimumFollowup)+ {+ return 0;+ }+ }+ }++ return 1;+}++# ifdef KBTS_DUMP+static void kbts__DumpCoverage(kbts__coverage *Coverage)+{+ KBTS_DUMPF("[");+ if(Coverage->Format == 1)+ {+ kbts_u16 *GlyphIds = KBTS__POINTER_AFTER(kbts_u16, Coverage);+ KBTS__FOR(GlyphIndex, 0, Coverage->Count)+ {+ KBTS_DUMPF("%x,", GlyphIds[GlyphIndex]);+ }+ }+ else if(Coverage->Format == 2)+ {+ kbts__range_record *Ranges = KBTS__POINTER_AFTER(kbts__range_record, Coverage);+ KBTS__FOR(RangeIndex, 0, Coverage->Count)+ {+ kbts__range_record *Range = &Ranges[RangeIndex];+ KBTS_DUMPF("%x..%x @ %u,", Range->StartGlyphId, Range->EndGlyphId, Range->StartCoverageIndex);+ }+ }+ KBTS_DUMPF("]");+}+# endif++static void kbts__ByteSwapChainedSequenceContextSubtable(kbts__byteswap_context *Context, kbts_u16 *Base)+{+ if(Base[0] == 1)+ {+ kbts__chained_sequence_context_1 *Subst = (kbts__chained_sequence_context_1 *)Base;+ Subst->ChainedSequenceRuleSetCount = kbts__ByteSwap16(Subst->ChainedSequenceRuleSetCount);+ kbts__ByteSwapArray16Context(KBTS__POINTER_AFTER(kbts_u16, Subst), Subst->ChainedSequenceRuleSetCount, Context);++ KBTS__FOR(SetIndex, 0, Subst->ChainedSequenceRuleSetCount)+ {+ kbts__ByteSwapChainedSequenceRuleSet(Context, kbts__GetChainedSequenceRuleSet(Subst, SetIndex));+ }+ }+ else if(Base[0] == 2)+ {+ kbts__chained_sequence_context_2 *Subst = (kbts__chained_sequence_context_2 *)Base;+ kbts__ByteSwapArray16Context(&Subst->BacktrackClassDefOffset, 4, Context);+ kbts__ByteSwapArray16Context(KBTS__POINTER_AFTER(kbts_u16, Subst), Subst->ChainedClassSequenceRuleSetCount, Context);++ kbts_u16 *BacktrackClassDefinition = KBTS__POINTER_OFFSET(kbts_u16, Subst, Subst->BacktrackClassDefOffset);+ kbts__ByteSwapClassDefinition(Context, BacktrackClassDefinition);++ kbts_u16 *InputClassDefinition = KBTS__POINTER_OFFSET(kbts_u16, Subst, Subst->InputClassDefOffset);+ kbts__ByteSwapClassDefinition(Context, InputClassDefinition);++ kbts_u16 *LookaheadClassDefinition = KBTS__POINTER_OFFSET(kbts_u16, Subst, Subst->LookaheadClassDefOffset);+ kbts__ByteSwapClassDefinition(Context, LookaheadClassDefinition);++ #ifdef KBTS_DUMP+ KBTS_DUMPF("Backtrack classes:\n");+ // kbts__DumpClassDefinition(BacktrackClassDefinition);+ KBTS_DUMPF("Input classes:\n");+ // kbts__DumpClassDefinition(InputClassDefinition);+ KBTS_DUMPF("Lookahead classes:\n");+ // kbts__DumpClassDefinition(LookaheadClassDefinition);+ #endif++ KBTS__FOR(SetIndex, 0, Subst->ChainedClassSequenceRuleSetCount)+ {+ kbts__chained_sequence_rule_set *Set = kbts__GetChainedClassSequenceRuleSet(Subst, SetIndex);+ kbts__ByteSwapChainedSequenceRuleSet(Context, Set);++ #ifdef KBTS_DUMP+ if(Set)+ {+ KBTS__FOR(RuleIndex, 0, Set->Count)+ {+ kbts__chained_sequence_rule *Rule = kbts__GetChainedClassSequenceRule(Set, RuleIndex);+ kbts__unpacked_chained_sequence_rule Unpacked = kbts__UnpackChainedSequenceRule(Rule, 0);++ KBTS_DUMPF("Backtrack: [");+ KBTS__FOR(BacktrackIndex, 0, Unpacked.BacktrackCount)+ {+ if(BacktrackIndex) KBTS_DUMPF(", ");+ KBTS_DUMPF("%u", Unpacked.Backtrack[BacktrackIndex]);+ }+ KBTS_DUMPF("]\n"+ "Input: [");+ KBTS__FOR(InputIndex, 1, Unpacked.InputCount)+ {+ if(InputIndex) KBTS_DUMPF(", ");+ KBTS_DUMPF("%u", Unpacked.Input[InputIndex - 1]);+ }+ KBTS_DUMPF("]\n"+ "Lookahead: [");+ KBTS__FOR(LookaheadIndex, 0, Unpacked.LookaheadCount)+ {+ if(LookaheadIndex) KBTS_DUMPF(", ");+ KBTS_DUMPF("%u", Unpacked.Lookahead[LookaheadIndex]);+ }+ KBTS_DUMPF("]\n"+ "Records: [");+ KBTS__FOR(RecordIndex, 0, Unpacked.RecordCount)+ {+ kbts__sequence_lookup_record *Record = &Unpacked.Records[RecordIndex];+ if(RecordIndex) KBTS_DUMPF(", ");+ KBTS_DUMPF("%u@%u", Record->LookupListIndex, Record->SequenceIndex);+ }+ KBTS_DUMPF("]\n");+ }+ }+ #endif+ }+ }+ else if(Base[0] == 3)+ {+ kbts__chained_sequence_context_3 *Subst = (kbts__chained_sequence_context_3 *)Base;+ kbts__unpacked_chained_sequence_context_3 Unpacked = kbts__UnpackChainedSequenceContext3(Subst, 1);++ kbts_un U16Count = Unpacked.BacktrackCount + Unpacked.InputCount + Unpacked.LookaheadCount + Unpacked.RecordCount * 2 + 4;+ kbts__ByteSwapArray16Context(&Subst->BacktrackGlyphCount, U16Count, Context);++ KBTS__FOR(BacktrackCoverageIndex, 0, Unpacked.BacktrackCount)+ {+ kbts__coverage *Coverage = KBTS__POINTER_OFFSET(kbts__coverage, Subst, Unpacked.BacktrackCoverageOffsets[BacktrackCoverageIndex]);++ kbts__ByteSwapCoverage(Context, Coverage);+ }++ KBTS__FOR(InputCoverageIndex, 0, Unpacked.InputCount)+ {+ kbts__coverage *Coverage = KBTS__POINTER_OFFSET(kbts__coverage, Subst, Unpacked.InputCoverageOffsets[InputCoverageIndex]);++ kbts__ByteSwapCoverage(Context, Coverage);+ }++ KBTS__FOR(LookaheadCoverageIndex, 0, Unpacked.LookaheadCount)+ {+ kbts__coverage *Coverage = KBTS__POINTER_OFFSET(kbts__coverage, Subst, Unpacked.LookaheadCoverageOffsets[LookaheadCoverageIndex]);++ kbts__ByteSwapCoverage(Context, Coverage);+ }++# ifdef KBTS_DUMP+ KBTS_DUMPF(" Backtrack: ");+ KBTS__FOR(BacktrackCoverageIndex, 0, Unpacked.BacktrackCount)+ {+ kbts__DumpCoverage(KBTS__POINTER_OFFSET(kbts__coverage, Subst, Unpacked.BacktrackCoverageOffsets[BacktrackCoverageIndex]));+ }+ KBTS_DUMPF("\n Input: ");+ KBTS__FOR(InputCoverageIndex, 0, Unpacked.InputCount)+ {+ kbts__DumpCoverage(KBTS__POINTER_OFFSET(kbts__coverage, Subst, Unpacked.InputCoverageOffsets[InputCoverageIndex]));+ }+ KBTS_DUMPF("\n Lookahead: ");+ KBTS__FOR(LookaheadCoverageIndex, 0, Unpacked.LookaheadCount)+ {+ kbts__DumpCoverage(KBTS__POINTER_OFFSET(kbts__coverage, Subst, Unpacked.LookaheadCoverageOffsets[LookaheadCoverageIndex]));+ }+ KBTS_DUMPF("\n Lookups: [");+ KBTS__FOR(RecordIndex, 0, Unpacked.RecordCount)+ {+ kbts__sequence_lookup_record *Record = &Unpacked.Records[RecordIndex];++ KBTS_DUMPF("%u@%u,", Record->LookupListIndex, Record->SequenceIndex);+ }+ KBTS_DUMPF("]\n");+# endif+ }+}++static void kbts__ByteSwapGsubLookupSubtable(kbts__byteswap_context *Context, kbts_u16 LookupType, kbts_u16 *Base)+{+ int Swap = !kbts__AlreadyVisited(Context, Base);+ while(Swap && (LookupType == 7))+ {+ kbts__extension *Subst = (kbts__extension *)Base;+ Subst->Format = kbts__ByteSwap16(Subst->Format);+ Subst->LookupType = kbts__ByteSwap16(Subst->LookupType);+ Subst->Offset = kbts__ByteSwap32(Subst->Offset);++ KBTS_DUMPF(" Type 7.1\n"+ " Offset %zu\n"+ " -> %zu\n",+ (char *)Base - Context->FileBase, (char *)Subst + Subst->Offset - Context->FileBase);++ Base = KBTS__POINTER_OFFSET(kbts_u16, Subst, Subst->Offset);+ LookupType = Subst->LookupType;++ Swap = !kbts__AlreadyVisited(Context, Base);+ }++ if(Swap)+ {+ *Base = kbts__ByteSwap16(*Base);++ KBTS_DUMPF(" Type %u.%u\n"+ " Offset %zu\n",+ LookupType, *Base, (char *)Base - Context->FileBase);++ if(kbts__GsubLookupBeginsWithCoverage(LookupType, Base[0]))+ {+ Base[1] = kbts__ByteSwap16(Base[1]);+ kbts__coverage *Coverage = KBTS__POINTER_OFFSET(kbts__coverage, Base, Base[1]);++ kbts__ByteSwapCoverage(Context, Coverage);++# ifdef KBTS_DUMP+ KBTS_DUMPF(" Coverage %u\n", Coverage->Format);+ if(Coverage->Format == 1)+ {+ kbts_u16 *GlyphIds = KBTS__POINTER_AFTER(kbts_u16, Coverage);+ KBTS__FOR(GlyphIndex, 0, Coverage->Count)+ {+ KBTS_DUMPF(" %x\n", GlyphIds[GlyphIndex]);+ }+ }+ else if(Coverage->Format == 2)+ {+ kbts__range_record *Ranges = KBTS__POINTER_AFTER(kbts__range_record, Coverage);+ KBTS__FOR(RangeIndex, 0, Coverage->Count)+ {+ kbts__range_record Range = Ranges[RangeIndex];+ KBTS_DUMPF(" %x..%x@%u..%u\n", Range.StartGlyphId, Range.EndGlyphId, Range.StartCoverageIndex, Range.StartCoverageIndex + (Range.EndGlyphId - Range.StartGlyphId));+ }+ }+# endif+ }++ switch(LookupType)+ {+ case 1:+ {+ kbts__single_substitution *Subst = (kbts__single_substitution *)Base;+ Subst->DeltaOrCount.GlyphCount = kbts__ByteSwap16(Subst->DeltaOrCount.GlyphCount);++# ifdef KBTS_DUMP+ if(Subst->Format == 1)+ {+ KBTS_DUMPF(" += %d\n", Subst->DeltaOrCount.DeltaGlyphId);+ }+# endif++ if(Subst->Format == 2)+ {+ kbts_u16 *GlyphIds = KBTS__POINTER_AFTER(kbts_u16, Subst);+ kbts__ByteSwapArray16Context(GlyphIds, Subst->DeltaOrCount.GlyphCount, Context);++ #ifdef KBTS_DUMP+ KBTS_DUMPF(" [");+ KBTS__FOR(IdIndex, 0, Subst->DeltaOrCount.GlyphCount)+ {+ if(IdIndex) KBTS_DUMPF(" ");+ KBTS_DUMPF("%x", GlyphIds[IdIndex]);+ }+ KBTS_DUMPF("]\n");+ #endif+ }+ }+ break;++ case 2:+ {+ kbts__multiple_substitution *Subst = (kbts__multiple_substitution *)Base;+ Subst->SequenceCount = kbts__ByteSwap16(Subst->SequenceCount);+ kbts__ByteSwapArray16Context(KBTS__POINTER_AFTER(kbts_u16, Subst), Subst->SequenceCount, Context);++ KBTS__FOR(SequenceIndex, 0, Subst->SequenceCount)+ {+ kbts__sequence *Sequence = kbts__GetSequence(Subst, SequenceIndex);++ if(!kbts__AlreadyVisited(Context, Sequence))+ {+ Sequence->GlyphCount = kbts__ByteSwap16(Sequence->GlyphCount);++ kbts__ByteSwapArray16Context(KBTS__POINTER_AFTER(kbts_u16, Sequence), Sequence->GlyphCount, Context);+ }++ #ifdef KBTS_DUMP+ KBTS_DUMPF(" [");+ kbts_u16 *SequenceGlyphIds = KBTS__POINTER_AFTER(kbts_u16, Sequence);+ KBTS__FOR(SequenceGlyphIndex, 0, Sequence->GlyphCount)+ {+ if(SequenceGlyphIndex) KBTS_DUMPF(" ");+ KBTS_DUMPF("%x", SequenceGlyphIds[SequenceGlyphIndex]);+ }+ KBTS_DUMPF("]\n");+ #endif+ }+ }+ break;++ case 3:+ {+ kbts__alternate_substitution *Subst = (kbts__alternate_substitution *)Base;+ Subst->AlternateSetCount = kbts__ByteSwap16(Subst->AlternateSetCount);+ kbts__ByteSwapArray16Context(KBTS__POINTER_AFTER(kbts_u16, Subst), Subst->AlternateSetCount, Context);++ KBTS__FOR(SetIndex, 0, Subst->AlternateSetCount)+ {+ kbts__alternate_set *Set = kbts__GetAlternateSet(Subst, SetIndex);++ if(!kbts__AlreadyVisited(Context, Set))+ {+ Set->GlyphCount = kbts__ByteSwap16(Set->GlyphCount);++ kbts__ByteSwapArray16Context(KBTS__POINTER_AFTER(kbts_u16, Set), Set->GlyphCount, Context);+ }++ #ifdef KBTS_DUMP+ KBTS_DUMPF(" [");+ kbts_u16 *SetGlyphIds = KBTS__POINTER_AFTER(kbts_u16, Set);+ KBTS__FOR(SetGlyphIndex, 0, Set->GlyphCount)+ {+ if(SetGlyphIndex) KBTS_DUMPF(" ");+ KBTS_DUMPF("%x", SetGlyphIds[SetGlyphIndex]);+ }+ KBTS_DUMPF("]\n");+ #endif+ }+ }+ break;++ case 4:+ {+ kbts__ligature_substitution *Subst = (kbts__ligature_substitution *)Base;+ Subst->LigatureSetCount = kbts__ByteSwap16(Subst->LigatureSetCount);+ kbts__ByteSwapArray16Context(KBTS__POINTER_AFTER(kbts_u16, Subst), Subst->LigatureSetCount, Context);++ KBTS__FOR(SetIndex, 0, Subst->LigatureSetCount)+ {+ kbts__ligature_set *Set = kbts__GetLigatureSet(Subst, SetIndex);++ if(!kbts__AlreadyVisited(Context, Set))+ {+ Set->Count = kbts__ByteSwap16(Set->Count);+ kbts__ByteSwapArray16Context(KBTS__POINTER_AFTER(kbts_u16, Set), Set->Count, Context);++ KBTS__FOR(LigatureIndex, 0, Set->Count)+ {+ kbts__ligature *Ligature = kbts__GetLigature(Set, LigatureIndex);++ if(!kbts__AlreadyVisited(Context, Ligature))+ {+ kbts__ByteSwapArray16Context(&Ligature->Glyph, 2, Context);+ kbts__ByteSwapArray16Context(KBTS__POINTER_AFTER(kbts_u16, Ligature), Ligature->ComponentCount - 1, Context);++# ifdef KBTS_DUMP+ KBTS_DUMPF("ligature: [");+ kbts_u16 *ComponentIds = KBTS__POINTER_AFTER(kbts_u16, Ligature);+ KBTS__FOR(ComponentIndex, 1, Ligature->ComponentCount)+ {+ KBTS_DUMPF("%x,", ComponentIds[ComponentIndex - 1]);+ }+ KBTS_DUMPF("] -> %x\n", Ligature->Glyph);+# endif+ }+ }+ }+ }++# ifdef KBTS_DUMP++# endif+ }+ break;++ case 5:+ {+ kbts__ByteSwapSequenceContextSubtable(Context, Base);+ }+ break;++ case 6:+ {+ kbts__ByteSwapChainedSequenceContextSubtable(Context, Base);+ }+ break;++ case 8:+ {+ kbts__reverse_chain_substitution *Subst = (kbts__reverse_chain_substitution *)Base;+ kbts__unpacked_reverse_chain_substitution Unpacked = kbts__UnpackReverseChainSubstitution(Subst, 1);++ kbts_un U16Count = Unpacked.BacktrackCount + Unpacked.GlyphCount + Unpacked.LookaheadCount + 3;+ kbts__ByteSwapArray16Context(&Subst->BacktrackGlyphCount, U16Count, Context);++ KBTS__FOR(BacktrackCoverageIndex, 0, Unpacked.BacktrackCount)+ {+ kbts__ByteSwapCoverage(Context, KBTS__POINTER_OFFSET(kbts__coverage, Subst, Unpacked.BacktrackCoverageOffsets[BacktrackCoverageIndex]));+ }+ KBTS__FOR(LookaheadCoverageIndex, 0, Unpacked.LookaheadCount)+ {+ kbts__ByteSwapCoverage(Context, KBTS__POINTER_OFFSET(kbts__coverage, Subst, Unpacked.LookaheadCoverageOffsets[LookaheadCoverageIndex]));+ }+ }+ break;+ }+ }+}++static void kbts__ByteSwapGposLookupSubtable(kbts__byteswap_context *Context, kbts_lookup_list *LookupList, kbts_u16 LookupType, kbts_u16 *Base)+{+ if(!kbts__AlreadyVisited(Context, Base))+ {+ *Base = kbts__ByteSwap16(*Base);++ KBTS_DUMPF(" GPOS subtable %u.%u\n", LookupType, *Base);++ if(kbts__GposLookupBeginsWithCoverage(LookupType, *Base))+ {+ kbts_u16 *CoverageOffset = &Base[1];+ *CoverageOffset = kbts__ByteSwap16(*CoverageOffset);++ kbts__coverage *Coverage = KBTS__POINTER_OFFSET(kbts__coverage, Base, *CoverageOffset);+ kbts__ByteSwapCoverage(Context, Coverage);+ }++ switch(LookupType)+ {+ case 1:+ {+ kbts__single_adjustment_1 *Adjust = (kbts__single_adjustment_1 *)Base;+ Adjust->ValueFormat = kbts__ByteSwap16(Adjust->ValueFormat);++ if(Adjust->Format == 1)+ {+ kbts_ByteSwapValueRecord(Context, Adjust, Adjust->ValueFormat, KBTS__POINTER_AFTER(kbts_u16, Adjust));+ }+ else if(Adjust->Format == 2)+ {+ kbts__single_adjustment_2 *Adjust2 = (kbts__single_adjustment_2 *)Base;+ Adjust2->RecordCount = kbts__ByteSwap16(Adjust2->RecordCount);++ kbts_u16 *At = KBTS__POINTER_AFTER(kbts_u16, Adjust2);+ KBTS__FOR(RecordIndex, 0, Adjust2->RecordCount)+ {+ kbts__unpacked_value_record Unpacked = kbts_ByteSwapValueRecord(Context, Adjust2, Adjust2->ValueFormat, At);++ At += Unpacked.Size;+ }+ }+ }+ break;++ case 2:+ {+ if(*Base == 1)+ {+ kbts__pair_adjustment_1 *Adjust = (kbts__pair_adjustment_1 *)Base;+ kbts__ByteSwapArray16Context(&Adjust->ValueFormat1, 3, Context);++ kbts_u16 *SetOffsets = KBTS__POINTER_AFTER(kbts_u16, Adjust);+ kbts__ByteSwapArray16Context(SetOffsets, Adjust->SetCount, Context);++ kbts_un Size1 = kbts__PopCount32(Adjust->ValueFormat1);+ kbts_un Size2 = kbts__PopCount32(Adjust->ValueFormat2);+ kbts_un PairRecordSize = Size1 + Size2 + 1;++ KBTS__FOR(SetIndex, 0, Adjust->SetCount)+ {+ kbts__pair_set *Set = KBTS__POINTER_OFFSET(kbts__pair_set, Adjust, SetOffsets[SetIndex]);++ if(!kbts__AlreadyVisited(Context, Set))+ {+ Set->Count = kbts__ByteSwap16(Set->Count);++ kbts_u16 *At = KBTS__POINTER_AFTER(kbts_u16, Set);++ KBTS__FOR(RecordIndex, 0, Set->Count)+ {+ kbts__pair_value_record *PairRecord = (kbts__pair_value_record *)(At + RecordIndex * PairRecordSize);++ PairRecord->SecondGlyph = kbts__ByteSwap16(PairRecord->SecondGlyph);+ kbts_u16 *Record = KBTS__POINTER_AFTER(kbts_u16, PairRecord);++ kbts__unpacked_value_record Unpacked1 = kbts_ByteSwapValueRecord(Context, Set, Adjust->ValueFormat1, Record);+ Record += Unpacked1.Size;+ kbts_ByteSwapValueRecord(Context, Set, Adjust->ValueFormat2, Record);+ }+ }+ }+ }+ else if(*Base == 2)+ {+ kbts__pair_adjustment_2 *Adjust = (kbts__pair_adjustment_2 *)Base;+ kbts__ByteSwapArray16Context(&Adjust->ValueFormat1, 6, Context);++ kbts__ByteSwapClassDefinition(Context, KBTS__POINTER_OFFSET(kbts_u16, Adjust, Adjust->ClassDefinition1Offset));+ kbts__ByteSwapClassDefinition(Context, KBTS__POINTER_OFFSET(kbts_u16, Adjust, Adjust->ClassDefinition2Offset));++ kbts_u16 *Records = KBTS__POINTER_AFTER(kbts_u16, Adjust);++ kbts_un Size1 = kbts__PopCount32(Adjust->ValueFormat1);+ kbts_un Size2 = kbts__PopCount32(Adjust->ValueFormat2);++ kbts_u16 *RecordPair = Records;+ KBTS__FOR(RecordIndex, 0, (kbts_un)Adjust->Class1Count * (kbts_un)Adjust->Class2Count)+ {+ kbts_ByteSwapValueRecord(Context, Adjust, Adjust->ValueFormat1, RecordPair);+ RecordPair += Size1;++ kbts_ByteSwapValueRecord(Context, Adjust, Adjust->ValueFormat2, RecordPair);+ RecordPair += Size2;+ }+ }+ }+ break;++ case 3:+ {+ kbts__cursive_attachment *Adjust = (kbts__cursive_attachment *)Base;+ Adjust->EntryExitCount = kbts__ByteSwap16(Adjust->EntryExitCount);+ kbts__ByteSwapArray16Context(KBTS__POINTER_AFTER(kbts_u16, Adjust), Adjust->EntryExitCount * 2, Context);++ kbts__entry_exit *EntryExits = KBTS__POINTER_AFTER(kbts__entry_exit, Adjust);+ KBTS__FOR(EntryExitIndex, 0, Adjust->EntryExitCount)+ {+ kbts__entry_exit *EntryExit = &EntryExits[EntryExitIndex];++ if(EntryExit->EntryAnchorOffset)+ {+ kbts__ByteSwapAnchor(Context, KBTS__POINTER_OFFSET(kbts__anchor, Adjust, EntryExit->EntryAnchorOffset));+ }++ if(EntryExit->ExitAnchorOffset)+ {+ kbts__ByteSwapAnchor(Context, KBTS__POINTER_OFFSET(kbts__anchor, Adjust, EntryExit->ExitAnchorOffset));+ }+ }+ }+ break;++ case 4:+ case 6:+ {+ kbts__mark_to_base_attachment *Adjust = (kbts__mark_to_base_attachment *)Base;+ kbts__ByteSwapArray16Context(&Adjust->BaseCoverageOffset, 4, Context);++ kbts__ByteSwapCoverage(Context, KBTS__POINTER_OFFSET(kbts__coverage, Adjust, Adjust->BaseCoverageOffset));+ kbts__ByteSwapMarkArray(Context, KBTS__POINTER_OFFSET(kbts__mark_array, Adjust, Adjust->MarkArrayOffset));+ kbts__ByteSwapBaseArray(Context, Adjust->MarkClassCount, KBTS__POINTER_OFFSET(kbts__base_array, Adjust, Adjust->BaseArrayOffset));+ }+ break;++ case 5:+ {+ kbts__mark_to_ligature_attachment *Adjust = (kbts__mark_to_ligature_attachment *)Base;+ kbts__ByteSwapArray16Context(&Adjust->LigatureCoverageOffset, 4, Context);++ kbts__ByteSwapCoverage(Context, KBTS__POINTER_OFFSET(kbts__coverage, Adjust, Adjust->LigatureCoverageOffset));+ kbts__ByteSwapMarkArray(Context, KBTS__POINTER_OFFSET(kbts__mark_array, Adjust, Adjust->MarkArrayOffset));++ kbts__ligature_array *LigatureArray = KBTS__POINTER_OFFSET(kbts__ligature_array, Adjust, Adjust->LigatureArrayOffset);+ if(!kbts__AlreadyVisited(Context, LigatureArray))+ {+ LigatureArray->Count = kbts__ByteSwap16(LigatureArray->Count);+ kbts__ByteSwapArray16Context(KBTS__POINTER_AFTER(kbts_u16, LigatureArray), LigatureArray->Count, Context);++ KBTS__FOR(AttachIndex, 0, LigatureArray->Count)+ {+ kbts__ligature_attach *Attach = kbts__GetLigatureAttach(LigatureArray, AttachIndex);++ if(!kbts__AlreadyVisited(Context, Attach))+ {+ Attach->Count = kbts__ByteSwap16(Attach->Count);++ kbts_u16 *AttachAnchorOffsets = KBTS__POINTER_AFTER(kbts_u16, Attach);+ kbts__ByteSwapArray16Context(AttachAnchorOffsets, Attach->Count * Adjust->MarkClassCount, Context);++ KBTS__FOR(ComponentIndex, 0, Attach->Count)+ {+ KBTS__FOR(MarkClass, 0, Adjust->MarkClassCount)+ {+ kbts__anchor *Anchor = kbts__GetLigatureAttachAnchor(Adjust, Attach, (kbts_u16)MarkClass, ComponentIndex);++ kbts__ByteSwapAnchor(Context, Anchor);+ }+ }+ }+ }+ }+ }+ break;++ case 7:+ {+ kbts__ByteSwapSequenceContextSubtable(Context, Base);+ }+ break;++ case 8:+ {+ kbts__ByteSwapChainedSequenceContextSubtable(Context, Base);+ }+ break;++ case 9:+ {+ // @Cleanup: Replace recursion with a loop at the start of this function!+ kbts__extension *Adjust = (kbts__extension *)Base;++ Adjust->LookupType = kbts__ByteSwap16(Adjust->LookupType);+ Adjust->Offset = kbts__ByteSwap32(Adjust->Offset);++ kbts__ByteSwapGposLookupSubtable(Context, LookupList, Adjust->LookupType, KBTS__POINTER_OFFSET(kbts_u16, Adjust, Adjust->Offset));+ }+ break;+ }+ }+}++static void *kbts__BlobTableData(kbts_blob_header *Header, kbts_blob_table_id TableId)+{+ void *Result = 0;+ kbts_blob_table *Table = &Header->Tables[TableId];++ if(Table->Length)+ {+ Result = KBTS__POINTER_OFFSET(void, Header, Table->OffsetFromStartOfFile);+ }++ return Result;+}+#define kbts__BlobTableDataType(Header, TableId, Type) (Type *)kbts__BlobTableData((Header), (TableId))++static kbts_glyph_classes kbts__GlyphClasses(kbts_font *Font, kbts_u32 Id)+{+ kbts_glyph_classes Result = KBTS__ZERO;++ // Look up all glyph classes.+ kbts__gdef *Gdef = kbts__BlobTableDataType(Font->Blob, KBTS_BLOB_TABLE_ID_GDEF, kbts__gdef);+ if(Gdef)+ {+ if(Gdef->ClassDefinitionOffset)+ {+ kbts_u16 *ClassDefBase = KBTS__POINTER_OFFSET(kbts_u16, Gdef, Gdef->ClassDefinitionOffset);+ Result.Class = kbts__GlyphClassFromTable(ClassDefBase, Id).Class;+ }++ if(Gdef->MarkAttachmentClassDefinitionOffset && (Result.Class == KBTS__GLYPH_CLASS_MARK))+ {+ kbts_u16 *MarkAttachmentClassDefBase = KBTS__POINTER_OFFSET(kbts_u16, Gdef, Gdef->MarkAttachmentClassDefinitionOffset);+ Result.MarkAttachmentClass = kbts__GlyphClassFromTable(MarkAttachmentClassDefBase, Id).Class;+ }+ }++ return Result;+}++static int kbts__ScriptIsWeak(kbts_script Script)+{+ int Result = (Script == KBTS_SCRIPT_DONT_KNOW) || (Script == KBTS_SCRIPT_DEFAULT) || (Script == KBTS_SCRIPT_DEFAULT2);+ return Result;+}++static int kbts__ShaperRtl(kbts_shaper Shaper)+{+ int Result = (Shaper == KBTS_SHAPER_ARABIC) || (Shaper == KBTS_SHAPER_HEBREW);+ return Result;+}++KBTS_EXPORT int kbts_CodepointToGlyphId(kbts_font *Font, int ICodepoint)+{+ int Result = 0;+ kbts_u32 Codepoint = (kbts_u32)ICodepoint;++ kbts_u16 *CmapBase = Font->Cmap;+ if(CmapBase)+ {+ switch(*CmapBase)+ {+ case 0:+ {+ kbts__cmap_0 *Cmap0 = (kbts__cmap_0 *)CmapBase;++ if((kbts_un)Codepoint < KBTS__ARRAY_LENGTH(Cmap0->GlyphIdArray))+ {+ Result = Cmap0->GlyphIdArray[Codepoint];+ }+ } break;++ case 2:+ {+ kbts__cmap_2 *Cmap2 = (kbts__cmap_2 *)CmapBase;+ kbts__sub_header *SubHeaders = KBTS__POINTER_AFTER(kbts__sub_header, Cmap2);++ kbts_u32 High = (Codepoint >> 8) & 0xFF;++ if(!(Codepoint & 0xFF00))+ {+ High = Codepoint & 0xFF;+ }++ // The Microsoft documentation doesn't mention that the SubHeaderKeys are indices multiplied by 8, for some+ // reason..! The Apple documentation does.+ kbts_u16 SubHeaderIndex = Cmap2->SubHeaderKeys[High] / 8;+ kbts__sub_header *SubHeader = &SubHeaders[SubHeaderIndex];++ if(!SubHeaderIndex)+ {+ // With SubHeader 0, we only use the first byte.+ Codepoint = High;+ }+ else+ {+ Codepoint = Codepoint & 0xFF;+ }++ kbts_u32 Offset = Codepoint - SubHeader->FirstCode;+ if(Offset < SubHeader->EntryCount)+ {+ kbts_u16 *GlyphIds = KBTS__POINTER_OFFSET(kbts_u16, &SubHeader->IdRangeOffset, SubHeader->IdRangeOffset);+ kbts_u16 GlyphId = GlyphIds[Offset];+ if(GlyphId)+ {+ GlyphId += SubHeader->IdDelta;+ }++ Result = GlyphId;+ }+ } break;++ case 4:+ {+ kbts__cmap_4 *Cmap4 = (kbts__cmap_4 *)CmapBase;+ kbts_un SegmentCount = Cmap4->SegmentCountTimesTwo / 2;+ kbts_u16 *EndCodes = KBTS__POINTER_AFTER(kbts_u16, Cmap4);+ kbts_u16 *StartCodes = EndCodes + SegmentCount + 1;+ kbts_s16 *IdDeltas = (kbts_s16 *)(StartCodes + SegmentCount);+ kbts_u16 *IdRangeOffsets = (kbts_u16 *)(IdDeltas + SegmentCount);+ kbts_un SegmentIndexOffset = 0;++ if(SegmentCount)+ {+ while(SegmentCount > 1)+ {+ kbts_un HalfCount = SegmentCount / 2;+ SegmentIndexOffset = (EndCodes[SegmentIndexOffset + HalfCount - 1] < Codepoint) ? (SegmentIndexOffset + HalfCount) : SegmentIndexOffset;+ SegmentCount -= HalfCount;+ }+ }++ kbts_u16 Start = StartCodes[SegmentIndexOffset];+ if((Codepoint >= Start) && (Codepoint <= EndCodes[SegmentIndexOffset]))+ {+ kbts_s16 Delta = IdDeltas[SegmentIndexOffset];+ kbts_u16 RangeOffset = IdRangeOffsets[SegmentIndexOffset];++ kbts_u16 GlyphId = (kbts_u16)Delta;+ if(RangeOffset)+ {+ GlyphId += *(&IdRangeOffsets[SegmentIndexOffset] + (Codepoint - Start) + RangeOffset / 2);+ }+ else+ {+ GlyphId += (kbts_u16)(Codepoint);+ }+ Result = GlyphId;+ }+ } break;++ case 6:+ {+ kbts__cmap_6 *Cmap6 = (kbts__cmap_6 *)CmapBase;+ kbts_u16 *GlyphIds = KBTS__POINTER_AFTER(kbts_u16, Cmap6);++ kbts_un Offset = Codepoint - Cmap6->FirstCode;+ if(Offset < Cmap6->EntryCount)+ {+ Result = GlyphIds[Offset];+ }+ } break;++ case 12:+ {+ kbts__cmap_12_13 *Cmap12 = (kbts__cmap_12_13 *)CmapBase;+ kbts__sequential_map_group *Groups = KBTS__POINTER_AFTER(kbts__sequential_map_group, Cmap12);++ kbts_un GlyphId = 0;+ kbts_un GroupCount = Cmap12->GroupCount;+ if(GroupCount)+ {+ while(GroupCount > 1)+ {+ kbts_un HalfCount = GroupCount / 2;+ Groups = (Groups[HalfCount - 1].EndCharacterCode < Codepoint) ? (Groups + HalfCount) : Groups;+ GroupCount -= HalfCount;+ }+ }++ if((Codepoint >= Groups->StartCharacterCode) && (Codepoint <= Groups->EndCharacterCode))+ {+ kbts_un Offset = Codepoint - Groups->StartCharacterCode;+ GlyphId = Groups->StartGlyphId + Offset;+ }++ Result = (int)GlyphId;+ } break;+ }+ }++ return Result;+}++KBTS_EXPORT kbts_glyph kbts_CodepointToGlyph(kbts_font *Font, int ICodepoint, kbts_glyph_config *Config, int UserId)+{+ kbts_u32 Codepoint = (kbts_u32)ICodepoint;++ kbts_glyph Result = KBTS__ZERO;+ Result.Codepoint = Codepoint;+ Result.Config = Config;+ Result.UserIdOrCodepointIndex = UserId;++ // Look up Unicode properties.+ Result.Decomposition = kbts__GetUnicodeDecomposition(Codepoint);+ Result.JoiningType = kbts__GetUnicodeJoiningType(Codepoint);+ Result.UnicodeFlags = kbts__GetUnicodeFlags(Codepoint);+ kbts_u16 SyllabicInfo = kbts__GetUnicodeSyllabicInfo(Codepoint);+ Result.SyllabicClass = kbts__GetSyllabicClass(SyllabicInfo);+ Result.SyllabicPosition = kbts__GetSyllabicPosition(SyllabicInfo);+ Result.CombiningClass = kbts__GetUnicodeCombiningClass(Codepoint);+ Result.UseClass = kbts__GetUnicodeUseClass(Codepoint);+ Result.ParentInfo = kbts__GetUnicodeParentInfo(Codepoint);++ Result.Id = (kbts_u16)kbts_CodepointToGlyphId(Font, ICodepoint);++ if(Font->Blob->Tables[KBTS_BLOB_TABLE_ID_GDEF].Length)+ {+ Result.Classes = kbts__GlyphClasses(Font, Result.Id);+ }+ else+ {+ // @Cleanup: This is garbage compatibility-with-broken-fonts code. I would very much like to get rid of it.+ if((Result.UnicodeFlags & KBTS_UNICODE_FLAG_DEFAULT_IGNORABLE) || !(Result.UnicodeFlags & KBTS_UNICODE_FLAG_NON_SPACING_MARK))+ {+ Result.Classes.Class = KBTS__GLYPH_CLASS_BASE;+ }+ else+ {+ Result.Classes.Class = KBTS__GLYPH_CLASS_MARK;+ }+ }++ return Result;+}++typedef struct kbts__iterate_features+{+ kbts__gsub_gpos *Header;+ kbts__feature_list *FeatureList;+ // @Incomplete+ // kbts__feature_variations *FeatureVariations;+ kbts__langsys *Langsys;++ kbts__feature_set EnabledFeatures;++ kbts_u32 CurrentFeatureTag;+ kbts_u32 CurrentFeatureFlag;++ kbts_u32 FeatureIndex;+ kbts__feature *Feature;+} kbts__iterate_features;++static kbts__iterate_features kbts__IterateFeatures(kbts_shape_config *Config, kbts_shaping_table ShapingTable, kbts__feature_set EnabledFeatures)+{+ kbts__iterate_features Result = KBTS__ZERO;++ kbts_blob_table_id TableId = (ShapingTable == KBTS_SHAPING_TABLE_GSUB) ? KBTS_BLOB_TABLE_ID_GSUB : KBTS_BLOB_TABLE_ID_GPOS;++ kbts__gsub_gpos *Header = kbts__BlobTableDataType(Config->Font->Blob, TableId, kbts__gsub_gpos);+ if(Header)+ {+ // @Incomplete+ // if(Header->Minor == 1)+ // {+ // Result.FeatureVariations = KBTS__POINTER_OFFSET(kbts__feature_variations, Header, Header->FeatureVariationsOffset);+ // }++ Result.FeatureList = KBTS__POINTER_OFFSET(kbts__feature_list, Header, Header->FeatureListOffset);+ Result.Header = Header;+ Result.Langsys = Config->Langsys[ShapingTable];+ Result.EnabledFeatures = EnabledFeatures;+ }++ return Result;+}++static int kbts__IsValidFeatureIteration(kbts__iterate_features *It)+{+ int Result = It->Langsys != 0;+ return Result;+}++static int kbts__NextFeature(kbts__iterate_features *It)+{+ int Result = 0;+ It->Feature = 0;++ if(kbts__IsValidFeatureIteration(It))+ {+ kbts_u16 *FeatureIndices = KBTS__POINTER_AFTER(kbts_u16, It->Langsys);+ // @Incomplete+ // kbts__feature_variations *FeatureVariations = It->FeatureVariations;+ while(It->FeatureIndex < It->Langsys->FeatureIndexCount)+ {+ kbts__feature_pointer Feature = kbts__GetFeature(It->FeatureList, FeatureIndices[It->FeatureIndex]);++ // We might need to swap out this feature with another.+ // Check for variations.+ // @Incomplete+ //if(FeatureVariations)+ //{+ // KBTS__FOR(VariationIndex, 0, FeatureVariations->RecordCount)+ // {+ // kbts__feature_variation_pointer Variation = kbts__GetFeatureVariation(FeatureVariations, VariationIndex);+ // KBTS__FOR(ConditionIndex, 0, Variation.ConditionSet->Count)+ // {+ // kbts__condition_1 *Condition = kbts__GetCondition(Variation.ConditionSet, ConditionIndex);+ // KBTS_ASSERT(0);+ // }+ // }+ //}++ It->FeatureIndex += 1;++ kbts_u32 FeatureId = kbts__FeatureTagToId(Feature.Tag);+ if(kbts__ContainsFeature(&It->EnabledFeatures, FeatureId))+ {+ It->Feature = Feature.Feature;+ It->CurrentFeatureTag = Feature.Tag;+ if(FeatureId && (FeatureId <= 32))+ {+ It->CurrentFeatureFlag = (1 << (FeatureId - 1)) & KBTS__GLYPH_FEATURE_MASK;+ }+ Result = 1;++ break;+ }+ }+ }++ return Result;+}++typedef struct kbts__iterate_lookups+{+ kbts_lookup_list *LookupList;+ kbts__feature *Feature;++ kbts__lookup *Lookup;+ kbts_u16 LookupIndex;++ kbts_u32 LookupIndexIndex;+} kbts__iterate_lookups;++static kbts__iterate_lookups kbts__IterateLookups(kbts_lookup_list *List, kbts__feature *Feature)+{+ kbts__iterate_lookups Result = KBTS__ZERO;+ Result.LookupList = List;+ Result.Feature = Feature;++ return Result;+}++static int kbts__NextLookup(kbts__iterate_lookups *It)+{+ int Result = 0;+ kbts__feature *Feature = It->Feature;++ if(It->LookupList && Feature && (It->LookupIndexIndex < Feature->LookupIndexCount))+ {+ kbts_u16 *LookupIndices = KBTS__POINTER_AFTER(kbts_u16, Feature);++ It->LookupIndex = LookupIndices[It->LookupIndexIndex];+ It->Lookup = kbts__GetLookup(It->LookupList, It->LookupIndex);++ Result = 1;+ It->LookupIndexIndex += 1;+ }++ return Result;+}++KBTS_INLINE void kbts__GsubMutate(kbts_font *Font, kbts_glyph *Glyph, kbts_u16 NewId, kbts_u32 Flags)+{+ Glyph->Id = NewId;+ Glyph->Classes = kbts__GlyphClasses(Font, NewId);+ Glyph->Flags = (Glyph->Flags & ~KBTS_GLYPH_FLAG_FIRST_IN_MULTIPLE_SUBSTITUTION) | Flags;+}++static kbts__op_list *kbts__ShaperOpLists[KBTS_SHAPER_COUNT] = {+ /* DEFAULT, */ &kbts__OpList_Default,+ /* ARABIC, */ &kbts__OpList_ArabicRclt,+ /* HANGUL, */ &kbts__OpList_Hangul,+ /* HEBREW, */ &kbts__OpList_Default,+ /* INDIC, */ &kbts__OpList_Indic,+ /* KHMER, */ &kbts__OpList_Khmer,+ /* MYANMAR, */ &kbts__OpList_Myanmar,+ /* TIBETAN, */ &kbts__OpList_Tibetan,+ /* USE, */ &kbts__OpList_Use,+};++typedef struct kbts__gsub_frame+{+ kbts_glyph *InputGlyph;++ // This isn't really an index into anything, per se.+ // It is just an offset that allows reordering for ShapeState->LookupOnePastLastGlyph.+ kbts_u32 StartIndex;++ kbts_u16 LookupIndex;+ kbts_u16 SubtableIndex;++ // Defined for nested lookups.+ kbts__sequence_lookup_record *Records;+ kbts_u16 RecordCount;+ kbts_u16 RecordIndex;+} kbts__gsub_frame;++#define KBTS__DLLIST_REMOVE(Node) do {(Node)->Prev->Next = (Node)->Next; (Node)->Next->Prev = (Node)->Prev;} while(0)+#define KBTS__DLLIST_INSERT_BEFORE(A, B) do{(A)->Next = (B); (A)->Prev = (B)->Prev; (A)->Prev->Next = (A)->Next->Prev = (A);} while(0)+#define KBTS__DLLIST_INSERT_AFTER(A, B) do{(A)->Prev = (B); (A)->Next = (B)->Next; (A)->Prev->Next = (A)->Next->Prev = (A);} while(0)+#define KBTS__DLLIST_SENTINEL_INIT(Sentinel) do{(Sentinel)->Prev = (Sentinel)->Next = (Sentinel);} while(0)+#define KBTS__DLLIST_SORT(First, OnePastLast, Member) \+ do \+ { \+ kbts_glyph *DllistSort_OneBeforeFirst = (First)->Prev; \+ kbts_glyph *DllistSort_OnePastLast = (OnePastLast); \+ for(int DllistSort_Swapped = 1; \+ DllistSort_Swapped; \+ ) \+ { \+ DllistSort_Swapped = 0; \+ kbts_glyph *DllistSort_Glyph0 = DllistSort_OneBeforeFirst->Next; \+ kbts_glyph *DllistSort_Glyph1 = DllistSort_Glyph0->Next; \+ while(DllistSort_Glyph1 != DllistSort_OnePastLast) \+ { \+ kbts_glyph *DllistSort_Next = DllistSort_Glyph1->Next; \+ \+ if(DllistSort_Glyph0->Member > DllistSort_Glyph1->Member) \+ { \+ KBTS__DLLIST_SWAP(DllistSort_Glyph0, DllistSort_Glyph1); \+ DllistSort_Swapped = 1; \+ } \+ else \+ { \+ DllistSort_Glyph0 = DllistSort_Glyph1; \+ } \+ \+ DllistSort_Glyph1 = DllistSort_Next; \+ } \+ } \+ } while(0)++#define KBTS__FOR_GLYPH(Storage, GlyphName) \+ for(kbts_glyph *GlyphName = (Storage)->GlyphSentinel.Next; \+ GlyphName != (kbts_glyph *)&(Storage)->GlyphSentinel; \+ GlyphName = GlyphName->Next)++static void KBTS__DLLIST_SWAP(kbts_glyph *A, kbts_glyph *B)+{+ kbts_glyph *APrev = A->Prev;+ kbts_glyph *ANext = A->Next;+ kbts_glyph *BPrev = B->Prev;+ kbts_glyph *BNext = B->Next;++ A->Prev = (BPrev == A) ? B : BPrev;+ A->Next = (BNext == A) ? B : BNext;+ B->Prev = (APrev == B) ? A : APrev;+ B->Next = (ANext == B) ? A : ANext;++ A->Prev->Next = A->Next->Prev = A;+ B->Prev->Next = B->Next->Prev = B;+}++static void kbts__NullAllocator(void *Data, kbts_allocator_op *Op)+{+ KBTS__UNUSED(Data);+ KBTS__UNUSED(Op);+}++static void kbts__DefaultAllocator(void *Data, kbts_allocator_op *Op)+{+ KBTS__UNUSED(Data);++ switch(Op->Kind)+ {+ case KBTS_ALLOCATOR_OP_KIND_ALLOCATE:+ {+ Op->Allocate.Pointer = KBTS_MALLOC(Data, Op->Allocate.Size);+ } break;++ case KBTS_ALLOCATOR_OP_KIND_FREE:+ {+ KBTS_FREE(Data, Op->Free.Pointer);+ } break;+ }+}++static void *kbts__AllocatorAllocate(kbts_allocator_function *Allocator, void *AllocatorData, kbts_un Size)+{+ kbts_allocator_op AllocatorOp = KBTS__ZERO;+ AllocatorOp.Kind = KBTS_ALLOCATOR_OP_KIND_ALLOCATE;+ AllocatorOp.Allocate.Size = (kbts_u32)Size;++ if(!Allocator)+ {+ Allocator = kbts__DefaultAllocator;+ }++ Allocator(AllocatorData, &AllocatorOp);++ void *Result = AllocatorOp.Allocate.Pointer;+ return Result;+}+#define kbts__AllocatorAllocateType(Allocator, AllocatorData, Type) (Type *)kbts_AllocatorAllocate((Allocator), (AllocatorData), sizeof(Type))+#define kbts__AllocatorAllocateArray(Allocator, AllocatorData, Type, Count) (Type *)kbts_AllocatorAllocate((Allocator), (AllocatorData), sizeof(Type) * (Count))++static void kbts__AllocatorFree(kbts_allocator_function *Allocator, void *AllocatorData, void *Pointer)+{+ if(Pointer)+ {+ kbts_allocator_op AllocatorOp = KBTS__ZERO;+ AllocatorOp.Kind = KBTS_ALLOCATOR_OP_KIND_FREE;+ AllocatorOp.Free.Pointer = Pointer;++ if(!Allocator)+ {+ Allocator = kbts__DefaultAllocator;+ }++ Allocator(AllocatorData, &AllocatorOp);+ }+}++static void kbts__EnsureArenaInitialized(kbts_arena *Arena)+{+ if(!Arena->BlockSentinel.Next)+ {+ KBTS__DLLIST_SENTINEL_INIT(&Arena->BlockSentinel);+ KBTS__DLLIST_SENTINEL_INIT(&Arena->FreeBlockSentinel);++ if(!Arena->Allocator)+ {+ Arena->Allocator = kbts__DefaultAllocator;+ }+ }+}++#define KBTS_ARENA_MIN_BLOCK_SIZE 4096+static kbts__arena_block *kbts__ArenaPushBlock(kbts_arena *Arena, kbts_un Size, kbts_un Align)+{+ kbts__arena_block *Result = (kbts__arena_block *)&Arena->BlockSentinel;++ if(!Arena->Error)+ {+ kbts_un BlockSize = sizeof(kbts__arena_block) + Size + KBTS_ALIGNOF(kbts__arena_block) + Align - 1;+ if(BlockSize < KBTS_ARENA_MIN_BLOCK_SIZE)+ {+ BlockSize = KBTS_ARENA_MIN_BLOCK_SIZE;+ }++ Result = (kbts__arena_block *)Arena->FreeBlockSentinel.Prev;+ if((Result == (kbts__arena_block *)&Arena->FreeBlockSentinel) ||+ ((Result->Size + sizeof(kbts__arena_block)) < BlockSize))+ {+ void *Base = kbts__AllocatorAllocate(Arena->Allocator, Arena->AllocatorData, BlockSize);++ if(Base)+ {+ Result = KBTS__ALIGN_POINTER(kbts__arena_block, Base, KBTS_ALIGNOF(kbts__arena_block));+ KBTS_MEMSET(Result, 0, sizeof(*Result));+ Result->BaseAllocation = Base;+ Result->Size = (kbts_un)(KBTS__POINTER_OFFSET(char, Base, BlockSize) - KBTS__POINTER_AFTER(char, Result));+ }+ else+ {+ Result = (kbts__arena_block *)&Arena->BlockSentinel;+ Arena->Error = 1;+ }+ }+ else+ {+ KBTS__DLLIST_REMOVE(&Result->Header);+ }++ KBTS__DLLIST_INSERT_BEFORE(&Result->Header, &Arena->BlockSentinel);++ Result->Used = 0;+ }++ return Result;+}++static int kbts__ArenaBlockIsValid(kbts_arena *Arena, kbts__arena_block *Block)+{+ int Result = Block && (&Block->Header != &Arena->BlockSentinel);+ return Result;+}++static void kbts__ClearArena(kbts_arena *Arena)+{+ kbts__EnsureArenaInitialized(Arena);++ kbts_arena_block_header *First = Arena->BlockSentinel.Next;+ kbts_arena_block_header *Last = Arena->BlockSentinel.Prev;++ if(kbts__ArenaBlockIsValid(Arena, (kbts__arena_block *)First))+ {+ First->Prev = Arena->FreeBlockSentinel.Prev;+ Last->Next = &Arena->FreeBlockSentinel;++ First->Prev->Next = First;+ Last->Next->Prev = Last;++ KBTS__DLLIST_SENTINEL_INIT(&Arena->BlockSentinel);+ }+}++static void *kbts__PushSize(kbts_arena *Arena, kbts_un Size, kbts_un Align)+{+ kbts__EnsureArenaInitialized(Arena);+ void *Result = 0;++ if(!Arena->Error)+ {+ kbts__arena_block *Block = (kbts__arena_block *)Arena->BlockSentinel.Prev;+ char *BlockMemory = KBTS__POINTER_AFTER(char, Block);++ if(kbts__ArenaBlockIsValid(Arena, Block))+ {+ char *Top = BlockMemory + Block->Used;+ char *TopAligned = KBTS__ALIGN_POINTER(char, Top, Align);++ if((kbts_un)((TopAligned + Size) - BlockMemory) <= Block->Size)+ {+ Result = TopAligned;+ }+ }++ if(!Result)+ {+ Block = kbts__ArenaPushBlock(Arena, Size, Align);++ if(kbts__ArenaBlockIsValid(Arena, Block))+ {+ BlockMemory = KBTS__POINTER_AFTER(char, Block);+ char *Top = BlockMemory + Block->Used;+ char *TopAligned = KBTS__ALIGN_POINTER(char, Top, Align);++ Result = TopAligned;+ }+ }++ if(Result)+ {+ Block->Used = (kbts_un)((char *)Result + Size - BlockMemory);+ KBTS_ASSERT(Block->Used <= Block->Size);+ }+ }++ return Result;+}+#define kbts__PushType(Arena, Type) (Type *)kbts__PushSize((Arena), sizeof(Type), KBTS_ALIGNOF(Type))+#define kbts__PushArray(Arena, Type, Count) (Type *)kbts__PushSize((Arena), sizeof(Type) * (Count), KBTS_ALIGNOF(Type))++static kbts__arena_lifetime kbts__BeginLifetime(kbts_arena *Arena)+{+ kbts__arena_block *Block = (kbts__arena_block *)Arena->BlockSentinel.Prev;+ kbts_un Used = 0;++ if(!Block)+ {+ Block = (kbts__arena_block *)&Arena->BlockSentinel;+ }++ if(kbts__ArenaBlockIsValid(Arena, Block))+ {+ Used = Block->Used;+ }++ kbts__arena_lifetime Result = KBTS__ZERO;+ Result.Arena = Arena;+ Result.BlockHeader = &Block->Header;+ Result.Used = Used;+ return Result;+}++static void kbts__EndLifetime(kbts__arena_lifetime *Lifetime)+{+ kbts_arena *Arena = Lifetime->Arena;+ if(Arena && !Arena->Error)+ {+ kbts__arena_block *Block = (kbts__arena_block *)Lifetime->BlockHeader;++ if(kbts__ArenaBlockIsValid(Lifetime->Arena, Block))+ {+ Block->Used = Lifetime->Used;+ }++ // This works even if Block is the sentinel.+ for(kbts_arena_block_header *Header = Block->Header.Next;+ kbts__ArenaBlockIsValid(Arena, (kbts__arena_block *)Header);+ )+ {+ kbts_arena_block_header *Next = Header->Next;++ KBTS__DLLIST_REMOVE(Header);+ KBTS__DLLIST_INSERT_BEFORE(Header, &Arena->FreeBlockSentinel);++ Header = Next;+ }+ }+}++static void kbts__MoveArena(kbts_arena *To, kbts_arena *From)+{+ *To = *From;++ if(To->BlockSentinel.Next != &From->BlockSentinel)+ {+ To->BlockSentinel.Next->Prev = To->BlockSentinel.Prev->Next = &To->BlockSentinel;+ }+ else+ {+ KBTS__DLLIST_SENTINEL_INIT(&To->BlockSentinel);+ }++ if(To->FreeBlockSentinel.Next != &From->FreeBlockSentinel)+ {+ To->FreeBlockSentinel.Next->Prev = To->FreeBlockSentinel.Prev->Next = &To->FreeBlockSentinel;+ }+ else+ {+ KBTS__DLLIST_SENTINEL_INIT(&To->FreeBlockSentinel);+ }+}++static void kbts__FreeArena(kbts_arena *Arena)+{+ kbts__EnsureArenaInitialized(Arena);++ kbts_arena StackArena;+ kbts__MoveArena(&StackArena, Arena);++ kbts_arena_block_header *Sentinels[2] = {&StackArena.BlockSentinel, &StackArena.FreeBlockSentinel};++ KBTS__FOR(SentinelIndex, 0, KBTS__ARRAY_LENGTH(Sentinels))+ {+ kbts_arena_block_header *Sentinel = Sentinels[SentinelIndex];++ for(kbts_arena_block_header *Header = Sentinel->Next;+ Header != Sentinel;+ )+ {+ kbts_arena_block_header *Next = Header->Next;+ kbts__arena_block *Block = (kbts__arena_block *)Header;++ kbts__AllocatorFree(StackArena.Allocator, StackArena.AllocatorData, Block->BaseAllocation);++ Header = Next;+ }+ }+}++static void kbts__ArenaAllocator(void *Data, kbts_allocator_op *Op)+{+ kbts_arena *Arena = (kbts_arena *)Data;++ if(Op->Kind == KBTS_ALLOCATOR_OP_KIND_ALLOCATE)+ {+ Op->Allocate.Pointer = kbts__PushSize(Arena, Op->Allocate.Size, 8);+ }+ // No free!+}++static int kbts__InitializeFixedMemoryArena(kbts_arena *Arena, void *Memory, kbts_un MemorySize)+{+ int Result = 0;+ KBTS_MEMSET(Arena, 0, sizeof(*Arena));+ Arena->Allocator = kbts__NullAllocator;+ kbts__EnsureArenaInitialized(Arena);++ char *BaseAligned = KBTS__ALIGN_POINTER(char, Memory, KBTS_ALIGNOF(kbts__arena_block));+ char *End = (char *)Memory + MemorySize;+ kbts_un TotalBlockSize = (kbts_un)(End - BaseAligned);++ if(TotalBlockSize >= sizeof(kbts__arena_block))+ {+ kbts__arena_block *Block = (kbts__arena_block *)BaseAligned;++ Block->Header.Prev = Block->Header.Next = &Arena->BlockSentinel;+ Block->Header.Prev->Next = Block->Header.Next->Prev = &Block->Header;+ Block->BaseAllocation = 0;+ Block->Size = TotalBlockSize - sizeof(kbts__arena_block);+ Block->Used = 0;++ Result = 1;+ }++ return Result;+}++static kbts_glyph *kbts__InsertGlyph(kbts_glyph_storage *Storage, kbts_glyph *Anchor, int InsertBeforeAnchor, kbts_glyph *BaseGlyph)+{+ kbts_glyph *Result = Storage->FreeGlyphSentinel.Next;++ if(Result != &Storage->FreeGlyphSentinel)+ {+ KBTS__DLLIST_REMOVE(Result);+ }+ else+ {+ Result = kbts__PushType(&Storage->Arena, kbts_glyph);+ }++ if(Result)+ {+ if(BaseGlyph)+ {+ *Result = *BaseGlyph;+ }++ if(InsertBeforeAnchor)+ {+ Result->Next = Anchor;+ Result->Prev = Anchor->Prev;+ }+ else+ {+ Result->Prev = Anchor;+ Result->Next = Anchor->Next;+ }++ Result->Prev->Next = Result->Next->Prev = Result;+ }+ else+ {+ Storage->Error = 1;+ }++ return Result;+}+static kbts_glyph *kbts__InsertGlyphBefore(kbts_glyph_storage *Storage, kbts_glyph *Anchor, kbts_glyph *BaseGlyph)+{+ kbts_glyph *Result = kbts__InsertGlyph(Storage, Anchor, 1, BaseGlyph);+ return Result;+}+static kbts_glyph *kbts__InsertGlyphAfter(kbts_glyph_storage *Storage, kbts_glyph *Anchor, kbts_glyph *BaseGlyph)+{+ kbts_glyph *Result = kbts__InsertGlyph(Storage, Anchor, 0, BaseGlyph);+ return Result;+}++static kbts_glyph *kbts__FreeGlyph(kbts__shape_scratchpad *Scratchpad, kbts_glyph_storage *Storage, kbts_glyph *Glyph)+{+ if(Glyph == Scratchpad->LookupOnePastLastGlyph)+ {+ Scratchpad->LookupOnePastLastGlyph = Glyph->Next;+ }+ if(Glyph == Scratchpad->Cluster.SentinelPrev)+ {+ Scratchpad->Cluster.SentinelPrev = Glyph->Prev;+ }+ if(Glyph == Scratchpad->Cluster.SentinelNext)+ {+ Scratchpad->Cluster.SentinelNext = Glyph->Next;+ }++ KBTS__DLLIST_REMOVE(Glyph);+ KBTS__DLLIST_INSERT_BEFORE(Glyph, (kbts_glyph *)&Storage->FreeGlyphSentinel);++ return Glyph;+}++static kbts_glyph *kbts__SetGlyphPreserveLinksAndUserId(kbts_glyph *Dest, kbts_glyph *Source)+{+ kbts_glyph *Prev = Dest->Prev;+ kbts_glyph *Next = Dest->Next;+ int UserId = Dest->UserIdOrCodepointIndex;++ *Dest = *Source;++ Dest->Prev = Prev;+ Dest->Next = Next;+ Dest->UserIdOrCodepointIndex = UserId;++ return Dest;+}++static int kbts__BeginFeatures(kbts__shape_scratchpad *Scratchpad, kbts_shape_config *Config, kbts_shaping_table ShapingTable)+{+ int Result = 0;+ kbts_blob_table_id TableId = (ShapingTable == KBTS_SHAPING_TABLE_GSUB) ? KBTS_BLOB_TABLE_ID_GSUB : KBTS_BLOB_TABLE_ID_GPOS;+ kbts__gsub_gpos *GsubGpos = kbts__BlobTableDataType(Config->Font->Blob, TableId, kbts__gsub_gpos);+ kbts__langsys *Langsys = Config->Langsys[ShapingTable];+ kbts_un FeatureStageIndex = Scratchpad->FeatureStagesRead - 1;++ Scratchpad->FeatureIndexIndex = 0;++ if(GsubGpos && Langsys && (FeatureStageIndex < Config->OpList.FeatureStageCount))+ {+ kbts__baked_feature_stage *BakedFeatureStage = &Config->FeatureStages[FeatureStageIndex];++ // @Incomplete+ // if(GsubGpos->Minor == 1)+ // {+ // kbts__feature_variations *FeatureVariations = KBTS__POINTER_OFFSET(kbts__feature_variations, GsubGpos, GsubGpos->FeatureVariationsOffset);+ // }+++ KBTS__FOR(FeatureIndex, 0, BakedFeatureStage->FeatureCount)+ {+ Scratchpad->BakedLookupSubtablesRead[FeatureIndex] = 0;+ }++ Result = 1;+ }++ return Result;+}++typedef struct kbts__sequence_lookup_result+{+ kbts__sequence_lookup_record *Records;+ kbts_un RecordCount;+ kbts_un InputSequenceCountIncludingSkippedGlyphs;++ kbts_glyph *OnePastLastGlyphMatched;++ // This is specified _nowhere_ in the docs, BUT some sequence lookups have 0 records, and exist just to prevent the+ // next lookups from executing.+ // So, checking if we got any records is not enough to figure out whether we need to "apply" this lookup.+ // We need to have an explicit bool as well.+ // Sigh.+ int Matched;+} kbts__sequence_lookup_result;++typedef struct kbts__sequence_match+{+ kbts_un MatchCount;+ kbts_un MatchOrSkipCount;+ kbts_glyph *OnePastMatchGlyph;+} kbts__sequence_match;++static kbts__sequence_match kbts__MatchCoverageSequence(kbts_glyph_storage *Storage, kbts__unpacked_lookup *Lookup, kbts_u32 SkipFlags, kbts_u32 SkipUnicodeFlags,+ void *Base, kbts_u16 *CoverageOffsets, kbts_un CoverageCount,+ kbts_glyph *AtGlyph, int Backward)+{+ kbts_un CoverageIndex = 0;+ kbts_un GlyphCounter = 0;+ while(kbts__GlyphIsValid(Storage, AtGlyph) && (CoverageIndex < CoverageCount))+ {+ kbts__coverage *Coverage = KBTS__POINTER_OFFSET(kbts__coverage, Base, CoverageOffsets[CoverageIndex]);++ if(!kbts__SkipGlyph(AtGlyph, Lookup, SkipFlags, SkipUnicodeFlags))+ {+ kbts__cover_glyph_result Cover = kbts__CoverGlyph(Coverage, AtGlyph->Id);++ if(Cover.Valid)+ {+ CoverageIndex += 1;+ }+ else+ {+ break;+ }+ }++ AtGlyph = Backward ? AtGlyph->Prev : AtGlyph->Next;+ GlyphCounter += 1;+ }++ kbts__sequence_match Result = KBTS__ZERO;+ Result.MatchCount = CoverageIndex;+ Result.MatchOrSkipCount = GlyphCounter;+ Result.OnePastMatchGlyph = AtGlyph;+ return Result;+}++static int kbts__BranchlessCompareArray16(kbts_u16 *A, kbts_u16 *B, kbts_un Count)+{+ kbts_u16 DifferenceMask = 0;+ KBTS__FOR(Index, 0, Count)+ {+ DifferenceMask |= A[Index] ^ B[Index];+ }+ return (int)DifferenceMask;+}++static kbts__sequence_lookup_result kbts__DoSequenceLookup(kbts_glyph_storage *Storage, kbts__unpacked_lookup *Lookup, kbts_u16 *Base, kbts__cover_glyph_result Cover,+ kbts_glyph *AtGlyph, kbts__skip_flags SkipFlags, kbts_u32 SkipUnicodeFlags)+{+ KBTS_INSTRUMENT_FUNCTION_BEGIN;+ kbts__sequence_lookup_result Result = KBTS__ZERO;+ Result.OnePastLastGlyphMatched = AtGlyph->Next;++ kbts_glyph *CurrentGlyph = AtGlyph;+ kbts_glyph *InputGlyph = AtGlyph->Next;+ kbts_un InputGlyphsTraversed = 1;+ kbts_glyph *BacktrackGlyph = AtGlyph->Prev;++ // Lookup types 7 and 8 are dispatch mechanisms. They do not substitute anything by themselves, they only point to+ // other rules.+ // Some formats have multiple rules; when that happens, we only ever match on the first one that fits.++ // We want to go to the right LookupType/SubtableFormat combination in a single jump, so we concatenate them here.+ // GSUB format 5 == GPOS format 7.+ // GSUB format 6 == GPOS format 8.+ switch(((kbts_u32)Lookup->Type << 16) | (kbts_u32)Base[0])+ {+ case 0x50001:+ case 0x70001:+ {+ kbts__sequence_context_1 *Subst = (kbts__sequence_context_1 *)Base;+ kbts__sequence_rule_set *Set = kbts__GetSequenceRuleSet(Subst, Cover.Index);++ if(Set)+ {+ kbts_u16 Ids[64]; // @Hardcoded+ kbts_u16 InputGlyphOffsets[64];+ kbts_glyph *InputGlyphs[64];+ kbts_un IdCount = 0;++ KBTS__FOR(RuleIndex, 0, Set->Count)+ {+ kbts__sequence_rule *Rule = kbts__GetSequenceRule(Set, RuleIndex);+ kbts_u16 *InputSequence = KBTS__POINTER_AFTER(kbts_u16, Rule);++ // @Hardcoded!+ KBTS_ASSERT(Rule->GlyphCount <= 64);++ while(kbts__GlyphIsValid(Storage, InputGlyph) && ((IdCount + 1) < Rule->GlyphCount))+ {+ if(!kbts__SkipGlyph(InputGlyph, Lookup, SkipFlags, SkipUnicodeFlags))+ {+ InputGlyphOffsets[IdCount] = (kbts_u16)InputGlyphsTraversed;+ InputGlyphs[IdCount] = InputGlyph;+ Ids[IdCount++] = InputGlyph->Id;+ }++ InputGlyph = InputGlyph->Next;+ InputGlyphsTraversed += 1;+ }++ if(((IdCount + 1) >= Rule->GlyphCount) &&+ !kbts__BranchlessCompareArray16(Ids, InputSequence, Rule->GlyphCount - 1))+ {+ Result.Records = (kbts__sequence_lookup_record *)(InputSequence + Rule->GlyphCount - 1);+ Result.RecordCount = Rule->SequenceLookupCount;+ Result.InputSequenceCountIncludingSkippedGlyphs = 1;+ if(Rule->GlyphCount > 1)+ {+ Result.InputSequenceCountIncludingSkippedGlyphs = InputGlyphOffsets[Rule->GlyphCount - 2] + 1;+ Result.OnePastLastGlyphMatched = InputGlyphs[Rule->GlyphCount - 2]->Next;+ }+ Result.Matched = 1;++ break;+ }+ }+ }+ }+ break;++ case 0x50002:+ case 0x70002:+ {+ kbts__sequence_context_2 *Subst = (kbts__sequence_context_2 *)Base;+ kbts_u16 *ClassDefinitionBase = KBTS__POINTER_OFFSET(kbts_u16, Subst, Subst->ClassDefOffset);++ // @Hardcoded!+ kbts_u16 InputClasses[64];+ kbts_u16 InputOffsets[64];+ kbts_glyph *InputGlyphs[64];+ kbts_un InputCount = 0;++ // For class-based contexts, the coverage index is not used.+ // Instead, we know which set to use based on the current glyph's class.+ // From the Microsoft docs:+ // The class value is used as the index into an array of offsets to ClassSequenceRuleSet tables.+ kbts__glyph_class_from_table_result CurrentGlyphClass = kbts__GlyphClassFromTable(ClassDefinitionBase, CurrentGlyph->Id);+ kbts__class_sequence_rule_set *Set = kbts__GetClassSequenceRuleSet(Subst, CurrentGlyphClass.Class);++ if((CurrentGlyphClass.Class < Subst->ClassSequenceRuleSetCount) && Set)+ {+ KBTS__FOR(RuleIndex, 0, Set->Count)+ {+ kbts__class_sequence_rule *Rule = kbts__GetClassSequenceRule(Set, RuleIndex);+ kbts_u16 *InputSequence = KBTS__POINTER_AFTER(kbts_u16, Rule);++ while(kbts__GlyphIsValid(Storage, InputGlyph) && ((InputCount + 1) < Rule->GlyphCount))+ {+ if(!kbts__SkipGlyph(InputGlyph, Lookup, SkipFlags, SkipUnicodeFlags))+ {+ InputOffsets[InputCount] = (kbts_u16)InputGlyphsTraversed;+ InputGlyphs[InputCount] = InputGlyph;+ InputClasses[InputCount++] = kbts__GlyphClassFromTable(ClassDefinitionBase, InputGlyph->Id).Class;+ }++ InputGlyph = InputGlyph->Next;+ InputGlyphsTraversed += 1;+ }++ if(((InputCount + 1) >= Rule->GlyphCount) &&+ !kbts__BranchlessCompareArray16(InputClasses, InputSequence, Rule->GlyphCount - 1))+ {+ Result.Records = (kbts__sequence_lookup_record *)(InputSequence + Rule->GlyphCount - 1);+ Result.RecordCount = Rule->SequenceLookupCount;+ Result.InputSequenceCountIncludingSkippedGlyphs = 1;+ if(Rule->GlyphCount > 1)+ {+ Result.InputSequenceCountIncludingSkippedGlyphs = InputOffsets[Rule->GlyphCount - 2] + 1;+ Result.OnePastLastGlyphMatched = InputGlyphs[Rule->GlyphCount - 2]->Next;+ }+ Result.Matched = 1;++ break;+ }+ }+ }+ }+ break;++ case 0x50003:+ case 0x70003:+ {+ kbts__sequence_context_3 *Subst = (kbts__sequence_context_3 *)Base;+ kbts_u16 *CoverageOffsets = KBTS__POINTER_AFTER(kbts_u16, Subst);++ kbts__sequence_match InputMatch = kbts__MatchCoverageSequence(Storage, Lookup, SkipFlags, SkipUnicodeFlags, Subst, CoverageOffsets, Subst->GlyphCount, AtGlyph, 0);++ if(InputMatch.MatchCount == Subst->GlyphCount)+ {+ Result.Records = (kbts__sequence_lookup_record *)(CoverageOffsets + Subst->GlyphCount);+ Result.RecordCount = Subst->SequenceLookupCount;+ Result.InputSequenceCountIncludingSkippedGlyphs = InputMatch.MatchOrSkipCount;+ Result.OnePastLastGlyphMatched = InputMatch.OnePastMatchGlyph;+ Result.Matched = 1;+ }+ }+ break;++ case 0x60001:+ case 0x80001:+ {+ kbts__chained_sequence_context_1 *Subst = (kbts__chained_sequence_context_1 *)Base;+ kbts__chained_sequence_rule_set *Set = kbts__GetChainedSequenceRuleSet(Subst, Cover.Index);++ if(Set)+ {+ // @Hardcoded!+ kbts_u16 BacktrackIds[64];+ kbts_u16 InputIds[64];+ kbts_u16 InputOffsets[64];+ kbts_glyph *InputGlyphs[64];+ kbts_un BacktrackCount = 0;+ kbts_un InputCount = 0;++ KBTS__FOR(RuleIndex, 0, Set->Count)+ {+ kbts__chained_sequence_rule *Rule = kbts__GetChainedSequenceRule(Set, RuleIndex);+ kbts__unpacked_chained_sequence_rule Unpacked = kbts__UnpackChainedSequenceRule(Rule, 0);++ while(kbts__GlyphIsValid(Storage, BacktrackGlyph) && (BacktrackCount < Unpacked.BacktrackCount))+ {+ if(!kbts__SkipGlyph(BacktrackGlyph, Lookup, SkipFlags, SkipUnicodeFlags))+ {+ BacktrackIds[BacktrackCount++] = BacktrackGlyph->Id;+ }++ BacktrackGlyph = BacktrackGlyph->Prev;+ }++ kbts_un TotalInputGlyphsRequired = Unpacked.InputCount - 1 + Unpacked.LookaheadCount;+ while(kbts__GlyphIsValid(Storage, InputGlyph) && (InputCount < TotalInputGlyphsRequired))+ {+ if(!kbts__SkipGlyph(InputGlyph, Lookup, SkipFlags, SkipUnicodeFlags))+ {+ InputGlyphs[InputCount] = InputGlyph;+ InputOffsets[InputCount] = (kbts_u16)InputGlyphsTraversed;+ InputIds[InputCount++] = InputGlyph->Id;+ }++ InputGlyph = InputGlyph->Next;+ InputGlyphsTraversed += 1;+ }++ if((BacktrackCount >= Unpacked.BacktrackCount) && (InputCount >= TotalInputGlyphsRequired) &&+ !kbts__BranchlessCompareArray16(BacktrackIds, Unpacked.Backtrack, Unpacked.BacktrackCount) &&+ !kbts__BranchlessCompareArray16(InputIds, Unpacked.Input, Unpacked.InputCount - 1) &&+ !kbts__BranchlessCompareArray16(InputIds + Unpacked.InputCount - 1, Unpacked.Lookahead, Unpacked.LookaheadCount))+ {+ Result.Records = Unpacked.Records;+ Result.RecordCount = Unpacked.RecordCount;+ Result.InputSequenceCountIncludingSkippedGlyphs = 1;+ if(Unpacked.InputCount > 1)+ {+ Result.InputSequenceCountIncludingSkippedGlyphs = InputOffsets[Unpacked.InputCount - 2] + 1;+ Result.OnePastLastGlyphMatched = InputGlyphs[Unpacked.InputCount - 2]->Next;+ }+ Result.Matched = 1;++ break;+ }+ }+ }+ }+ break;++ case 0x60002:+ case 0x80002:+ {+ kbts__chained_sequence_context_2 *Subst = (kbts__chained_sequence_context_2 *)Base;+ kbts_u16 *BacktrackClassDefinition = KBTS__POINTER_OFFSET(kbts_u16, Subst, Subst->BacktrackClassDefOffset);+ kbts_u16 *InputClassDefinition = KBTS__POINTER_OFFSET(kbts_u16, Subst, Subst->InputClassDefOffset);+ kbts_u16 *LookaheadClassDefinition = KBTS__POINTER_OFFSET(kbts_u16, Subst, Subst->LookaheadClassDefOffset);++ // @Incomplete: Do this with all sequence types!++ // @Hardcoded: Pre-alloc this using LookupInfo!+ kbts_u16 BacktrackClasses[64];+ kbts_u16 InputClasses[64];+ kbts_u16 InputClassOffsets[64];+ kbts_glyph *InputGlyphs[64];+ kbts_u16 LookaheadClasses[64];+ kbts_un BacktrackClassCount = 0;+ kbts_un InputClassCount = 0;++ // Just like lookup 5.2, we use the current glyph class to figure out which set to look up.+ // From the Microsoft docs:+ // If found, the client then searches in the class definition table to find the class value assigned to the+ // current glyph. The class value is used as the index into an array of offsets to ChainedClassSequenceRuleSet+ // tables.+ //+ kbts_u16 CurrentGlyphClass = kbts__GlyphClassFromTable(InputClassDefinition, CurrentGlyph->Id).Class;+ kbts__chained_sequence_rule_set *Set = kbts__GetChainedClassSequenceRuleSet(Subst, CurrentGlyphClass);+ // If the glyph was contained in the coverage table, then it should have a valid class.+ // Nevertheless, one Harfbuzz test font did not remove out-of-bounds glyph classes from the class definition+ // table here, so we double-check it here.+ // (It is also possible for a font to want to reuse the same class definition table across multiple lookups,+ // in which case ignoring these classes becomes a feature.)+ if((CurrentGlyphClass < Subst->ChainedClassSequenceRuleSetCount) && Set)+ {+ KBTS__FOR(RuleIndex, 0, Set->Count)+ {+ kbts__chained_sequence_rule *Rule = kbts__GetChainedClassSequenceRule(Set, RuleIndex);+ kbts__unpacked_chained_sequence_rule Unpacked = kbts__UnpackChainedSequenceRule(Rule, 0);++ // @Hardcoded+ KBTS_ASSERT(Unpacked.BacktrackCount <= 64);+ KBTS_ASSERT(Unpacked.InputCount <= 64);+ KBTS_ASSERT(Unpacked.LookaheadCount <= 64);++ while(kbts__GlyphIsValid(Storage, BacktrackGlyph) && (BacktrackClassCount < Unpacked.BacktrackCount))+ {+ if(!kbts__SkipGlyph(BacktrackGlyph, Lookup, SkipFlags, SkipUnicodeFlags))+ {+ // @Robustness: Do we want to break if we don't find a class?+ kbts__glyph_class_from_table_result Class = kbts__GlyphClassFromTable(BacktrackClassDefinition, BacktrackGlyph->Id);+ BacktrackClasses[BacktrackClassCount++] = Class.Class;+ }++ BacktrackGlyph = BacktrackGlyph->Prev;+ }++ kbts_un InputClassCountRequired = Unpacked.InputCount - 1 + Unpacked.LookaheadCount;+ while(kbts__GlyphIsValid(Storage, InputGlyph) && (InputClassCount < InputClassCountRequired))+ {+ if(!kbts__SkipGlyph(InputGlyph, Lookup, SkipFlags, SkipUnicodeFlags))+ {+ kbts__glyph_class_from_table_result InputClass = kbts__GlyphClassFromTable(InputClassDefinition, InputGlyph->Id);+ // In many cases, the font designer just wants to match "a set of glyphs" forward,+ // and it doesn't matter whether those glyphs are in the input sequence or part of the lookahead.+ // This happens often enough that we care to special-case it.+ kbts__glyph_class_from_table_result LookaheadClass = InputClass;+ if(LookaheadClassDefinition != InputClassDefinition)+ {+ LookaheadClass = kbts__GlyphClassFromTable(LookaheadClassDefinition, InputGlyph->Id);+ }++ // @Robustness: Do we want to break if we don't find a class?+ InputGlyphs[InputClassCount] = InputGlyph;+ InputClassOffsets[InputClassCount] = (kbts_u16)InputGlyphsTraversed;+ InputClasses[InputClassCount] = InputClass.Class;+ LookaheadClasses[InputClassCount] = LookaheadClass.Class;++ InputClassCount += 1;+ }++ InputGlyph = InputGlyph->Next;+ InputGlyphsTraversed += 1;+ }++ if((BacktrackClassCount >= Unpacked.BacktrackCount) &&+ (InputClassCount >= InputClassCountRequired) &&+ !kbts__BranchlessCompareArray16(BacktrackClasses, Unpacked.Backtrack, Unpacked.BacktrackCount) &&+ !kbts__BranchlessCompareArray16(InputClasses, Unpacked.Input, Unpacked.InputCount - 1) &&+ !kbts__BranchlessCompareArray16(LookaheadClasses + Unpacked.InputCount - 1, Unpacked.Lookahead, Unpacked.LookaheadCount))+ {+ Result.Records = Unpacked.Records;+ Result.RecordCount = Unpacked.RecordCount;+ Result.InputSequenceCountIncludingSkippedGlyphs = 1;+ if(Unpacked.InputCount > 1)+ {+ Result.InputSequenceCountIncludingSkippedGlyphs = InputClassOffsets[Unpacked.InputCount - 2] + 1;+ Result.OnePastLastGlyphMatched = InputGlyphs[Unpacked.InputCount - 2]->Next;+ }+ Result.Matched = 1;++ break;+ }+ }+ }+ }+ break;++ case 0x60003:+ case 0x80003:+ {+ kbts__chained_sequence_context_3 *Subst = (kbts__chained_sequence_context_3 *)Base;+ kbts__unpacked_chained_sequence_context_3 Unpacked = kbts__UnpackChainedSequenceContext3(Subst, 0);++ // Since chained sequence contexts roll the coverage for the first glyph into an array, you'd think that+ // the matching logic for the first glyph would be the same as for any other glyph in that array.+ // You'd be wrong!+ // The first glyph does _not_ have to pass glyph filtering logic. It just has to pass the coverage test.+ // Every other input glyph still does, though.+ kbts__cover_glyph_result CurrentCover = KBTS__ZERO;+ CurrentCover.Valid = !Unpacked.InputCount || kbts__GlyphPassesLookupFilter(CurrentGlyph, Lookup);+ if(Unpacked.InputCount)+ {+ kbts__coverage *CurrentCoverage = KBTS__POINTER_OFFSET(kbts__coverage, Subst, Unpacked.InputCoverageOffsets[0]);+ CurrentCover = kbts__CoverGlyph(CurrentCoverage, CurrentGlyph->Id);+ }++ if(CurrentCover.Valid)+ {+ kbts__sequence_match BacktrackMatch = kbts__MatchCoverageSequence(Storage, Lookup, SkipFlags, SkipUnicodeFlags, Subst, Unpacked.BacktrackCoverageOffsets, Unpacked.BacktrackCount, BacktrackGlyph, 1);+ kbts__sequence_match InputMatch = kbts__MatchCoverageSequence(Storage, Lookup, SkipFlags, SkipUnicodeFlags, Subst, Unpacked.InputCoverageOffsets + 1, Unpacked.InputCount - 1, InputGlyph, 0);+ kbts_un MatchingInputGlyphCount = 1 + InputMatch.MatchCount;+ kbts_un MatchedOrSkippedInputGlyphCount = 1 + InputMatch.MatchOrSkipCount;+ kbts__sequence_match LookaheadMatch = kbts__MatchCoverageSequence(Storage, Lookup, SkipFlags, SkipUnicodeFlags, Subst, Unpacked.LookaheadCoverageOffsets, Unpacked.LookaheadCount, InputMatch.OnePastMatchGlyph, 0);++ if((BacktrackMatch.MatchCount == Unpacked.BacktrackCount) && ((MatchingInputGlyphCount) == Unpacked.InputCount) && (LookaheadMatch.MatchCount == Unpacked.LookaheadCount))+ {+ Result.Records = Unpacked.Records;+ Result.RecordCount = Unpacked.RecordCount;+ Result.InputSequenceCountIncludingSkippedGlyphs = MatchedOrSkippedInputGlyphCount;+ Result.OnePastLastGlyphMatched = InputMatch.OnePastMatchGlyph;+ Result.Matched = 1;++ break;+ }+ }+ }+ break;+ }++ KBTS_INSTRUMENT_FUNCTION_END;+ return Result;+}++static void kbts__ApplyValueRecord(kbts_glyph *Glyph, kbts__unpacked_value_record *Unpacked)+{+ Glyph->OffsetX += Unpacked->PlacementX;+ Glyph->OffsetY += Unpacked->PlacementY;++ Glyph->AdvanceX += Unpacked->AdvanceX;+ Glyph->AdvanceY += Unpacked->AdvanceY;+}++static int kbts__NextGlyph(kbts_glyph_storage *Storage, kbts__unpacked_lookup *Lookup, kbts_glyph *AtGlyph, kbts__skip_flags SkipFlags, kbts_u32 SkipUnicodeFlags, kbts_glyph **Match, int Backward)+{+ kbts_glyph *MatchingGlyph = 0;++ while(kbts__GlyphIsValid(Storage, AtGlyph))+ {+ if(!kbts__SkipGlyph(AtGlyph, Lookup, SkipFlags, SkipUnicodeFlags))+ {+ MatchingGlyph = AtGlyph;+ break;+ }+ else+ {+ AtGlyph = Backward ? AtGlyph->Prev : AtGlyph->Next;+ }+ }++ *Match = MatchingGlyph;+ return MatchingGlyph != 0;+}++static void kbts__AttachGlyph(kbts_glyph_storage *Storage, kbts_glyph *Parent, kbts_glyph *Child, kbts_s32 X, kbts_s32 Y)+{+ kbts_s32 DeltaOffsetX = X - Child->OffsetX;+ kbts_s32 DeltaOffsetY = Y - Child->OffsetY;++ Child->OffsetX = X;+ Child->OffsetY = Y;+ Child->Flags |= KBTS_GLYPH_FLAG_USED_IN_GPOS;+ Child->AttachGlyph = Parent;++ Parent->Flags |= KBTS_GLYPH_FLAG_USED_IN_GPOS;++ for(kbts_glyph *MiddleGlyph = Parent->Next;+ MiddleGlyph != Child;+ MiddleGlyph = MiddleGlyph->Next)+ {+ MiddleGlyph->Flags |= KBTS_GLYPH_FLAG_NO_BREAK;+ }++ // @Speed: Fuck this.+ // Attachments can happen in anti-topological order, so we have to fix them up here.+ // We should store glyph parent/child indices instead of traversing all glyphs.+ for(kbts_glyph *PostGlyph = Child->Next;+ kbts__GlyphIsValid(Storage, PostGlyph);+ PostGlyph = PostGlyph->Next)+ {+ if(PostGlyph->AttachGlyph == Child)+ {+ PostGlyph->OffsetX += DeltaOffsetX;+ PostGlyph->OffsetY += DeltaOffsetY;+ }+ }+}++static void kbts__SetLookupOnePastLastGlyph(kbts__shape_scratchpad *Scratchpad, kbts_un Index, kbts_glyph *Glyph)+{+ if(Index > Scratchpad->LookupOnePastLastGlyphIndex)+ {+ Scratchpad->LookupOnePastLastGlyphIndex = (kbts_u32)Index;+ Scratchpad->LookupOnePastLastGlyph = Glyph;+ }+}++typedef kbts_u32 kbts__cursive_flags;+enum kbts__cursive_flags_enum+{+ KBTS__CURSIVE_FLAG_NONE,+ KBTS__CURSIVE_FLAG_START = (1 << 0),+ KBTS__CURSIVE_FLAG_END = (1 << 1),+};++KBTS_INLINE kbts__cursive_flags kbts__GetCursiveFlags(kbts_glyph *Glyph)+{+ kbts__cursive_flags Result = (kbts__cursive_flags)Glyph->MarkOrdering;+ return Result;+}++KBTS_INLINE void kbts__SetCursiveFlags(kbts_glyph *Glyph, kbts__cursive_flags CursiveFlags)+{+ Glyph->MarkOrdering = (kbts_u8)CursiveFlags;+}++static int kbts__DoSingleAdjustment(kbts__shape_scratchpad *Scratchpad, kbts_shape_config *Config, kbts_glyph_storage *Storage,+ kbts_lookup_list *LookupList, kbts_un LookupIndex, kbts_un SubtableIndex, kbts__unpacked_lookup *Lookup, kbts_u16 *Base,+ kbts_glyph *CurrentGlyph, kbts_un StartIndex, kbts__skip_flags RequestedSkipFlags)+{+ KBTS_INSTRUMENT_FUNCTION_BEGIN;+ kbts_unicode_flags SkipUnicodeFlags = KBTS_UNICODE_FLAG_DEFAULT_IGNORABLE;+ kbts__skip_flags RegularSkipFlags = KBTS__SKIP_FLAGS_GPOS_REGULAR(RequestedSkipFlags);+ kbts__skip_flags SequenceSkipFlags = KBTS__SKIP_FLAGS_GPOS_SEQUENCE(RequestedSkipFlags);++ int Result = 0;++ kbts_un OnePastLastGlyphIndex = StartIndex + 1;+ kbts_glyph *OnePastLastGlyph = CurrentGlyph->Next;++ if(kbts__GlyphsIncludedInLookupSubtable(Storage, Config->Font, 1, Lookup, LookupIndex, SubtableIndex, CurrentGlyph, SequenceSkipFlags, SkipUnicodeFlags))+ {+ // CAREFUL: We want kbts__unpacked_lookup to be a useful bag-of-arguments type, but, for extension+ // lookups, each subtable may specify its own lookup type, so we save it here and restore it at+ // the end of this function.+ kbts_u16 OriginalLookupType = Lookup->Type;++ while(Lookup->Type == 9)+ {+ kbts__extension *Extension = (kbts__extension *)Base;++ Lookup->Type = Extension->LookupType;+ Base = KBTS__POINTER_OFFSET(kbts_u16, Extension, Extension->Offset);+ }++ kbts__cover_glyph_result Cover = KBTS__ZERO;+ Cover.Valid = kbts__GlyphPassesLookupFilter(CurrentGlyph, Lookup);+ kbts__coverage *Coverage = 0;+ if(Cover.Valid && kbts__GposLookupBeginsWithCoverage(Lookup->Type, Base[0]))+ {+ kbts_u16 *CoverageOffset = Base + 1;+ Coverage = KBTS__POINTER_OFFSET(kbts__coverage, Base, *CoverageOffset);+ Cover = kbts__CoverGlyph(Coverage, CurrentGlyph->Id);+ }++ if(Cover.Valid)+ {+ kbts_un OnePastLastGlyphOffset = 0;++ switch(Lookup->Type)+ {+ case 1:+ {+ kbts__unpacked_value_record Unpacked = KBTS__ZERO;++ if(Base[0] == 1)+ {+ kbts__single_adjustment_1 *Adjust = (kbts__single_adjustment_1 *)Base;++ Unpacked = kbts__UnpackValueRecord(Adjust, Adjust->ValueFormat, KBTS__POINTER_AFTER(kbts_u16, Adjust));+ }+ else if(Base[0] == 2)+ {+ kbts__single_adjustment_2 *Adjust = (kbts__single_adjustment_2 *)Base;++ kbts_un RecordSize = kbts__PopCount32(Adjust->ValueFormat);+ kbts_u16 *Records = KBTS__POINTER_AFTER(kbts_u16, Adjust);+ kbts_u16 *Record = Records + RecordSize * Cover.Index;++ Unpacked = kbts__UnpackValueRecord(Adjust, Adjust->ValueFormat, Record);+ }++ kbts__ApplyValueRecord(CurrentGlyph, &Unpacked);+ CurrentGlyph->Flags |= KBTS_GLYPH_FLAG_USED_IN_GPOS;++ Result = 1;+ }+ break;++ case 2:+ {+ kbts_glyph *NextGlyph;+ if(kbts__NextGlyph(Storage, Lookup, CurrentGlyph->Next, RegularSkipFlags, SkipUnicodeFlags, &NextGlyph, 0))+ {+ kbts_u32 NextGlyphId = NextGlyph->Id;++ kbts__unpacked_value_record Unpacked1 = KBTS__ZERO;+ kbts__unpacked_value_record Unpacked2 = KBTS__ZERO;+ int Valid = 0;++ if(Base[0] == 1)+ {+ kbts__pair_adjustment_1 *Adjust = (kbts__pair_adjustment_1 *)Base;++ kbts_un Size1 = kbts__PopCount32(Adjust->ValueFormat1);+ kbts_un Size2 = kbts__PopCount32(Adjust->ValueFormat2);++ kbts_u16 *SetOffsets = KBTS__POINTER_AFTER(kbts_u16, Adjust);+ kbts__pair_set *Set = KBTS__POINTER_OFFSET(kbts__pair_set, Adjust, SetOffsets[Cover.Index]);++ kbts_un PairRecordSize = Size1 + Size2 + 1; // + 1 because each pair stores the next glyph ID.+ kbts__pair_value_record *PairRecords = KBTS__POINTER_AFTER(kbts__pair_value_record, Set);+ KBTS__FOR(PairIndex, 0, Set->Count)+ {+ kbts__pair_value_record *PairRecord = PairRecords + PairRecordSize * PairIndex;++ if(PairRecord->SecondGlyph == NextGlyphId)+ {+ kbts_u16 *Records = KBTS__POINTER_AFTER(kbts_u16, PairRecord);++ Unpacked1 = kbts__UnpackValueRecord(Adjust, Adjust->ValueFormat1, Records);+ Records += Unpacked1.Size;+ Unpacked2 = kbts__UnpackValueRecord(Adjust, Adjust->ValueFormat2, Records);+ Valid = 1;+ }+ }+ }+ else if(Base[0] == 2)+ {+ kbts__pair_adjustment_2 *Adjust = (kbts__pair_adjustment_2 *)Base;+ kbts_u16 *ClassDef1 = KBTS__POINTER_OFFSET(kbts_u16, Adjust, Adjust->ClassDefinition1Offset);+ kbts_u16 *ClassDef2 = KBTS__POINTER_OFFSET(kbts_u16, Adjust, Adjust->ClassDefinition2Offset);++ kbts_un Size1 = kbts__PopCount32(Adjust->ValueFormat1);+ kbts_un Size2 = kbts__PopCount32(Adjust->ValueFormat2);+ kbts_un PairRecordSize = Size1 + Size2;+ kbts_u16 *PairRecords = KBTS__POINTER_AFTER(kbts_u16, Adjust);++ // From the Microsoft docs:+ // PairPosFormat2 requires that each glyph in all pairs be assigned to a class, which is+ // identified by an integer called a class value.+ // This _seems_ like it would mean that, if either glyph is not specified in its respective+ // class definition table, then we should skip the lookup.+ // However, this seems wrong in practice. Undefined classes seem to just default to 0, and then+ // the bounds check takes care of deciding whether the lookup is okay to apply or not.+ kbts__glyph_class_from_table_result Class1 = kbts__GlyphClassFromTable(ClassDef1, CurrentGlyph->Id);+ kbts__glyph_class_from_table_result Class2 = kbts__GlyphClassFromTable(ClassDef2, NextGlyphId);+ if((Class1.Class < Adjust->Class1Count) && (Class2.Class < Adjust->Class2Count))+ {+ kbts_u16 *PairRecord = PairRecords + Class1.Class * PairRecordSize * Adjust->Class2Count + Class2.Class * PairRecordSize;++ Unpacked1 = kbts__UnpackValueRecord(Adjust, Adjust->ValueFormat1, PairRecord);+ PairRecord += Size1;++ Unpacked2 = kbts__UnpackValueRecord(Adjust, Adjust->ValueFormat2, PairRecord);+ PairRecord += Size2;+ Valid = 1;+ }+ }++ if(Valid)+ {+ kbts__ApplyValueRecord(CurrentGlyph, &Unpacked1);+ CurrentGlyph->Flags |= KBTS_GLYPH_FLAG_USED_IN_GPOS;++ kbts__ApplyValueRecord(NextGlyph, &Unpacked2);+ NextGlyph->Flags |= KBTS_GLYPH_FLAG_USED_IN_GPOS;++ Result = 1;+ OnePastLastGlyph = Unpacked2.Size ? NextGlyph->Next : CurrentGlyph->Next;+ }+ }+ }+ break;++ // All three types of attachment (cursive, mark-to-base, mark-to-ligature) look backward instead of forward.+ case 3:+ {+ kbts__cursive_attachment *Adjust = (kbts__cursive_attachment *)Base;+ kbts__entry_exit *EntryExits = KBTS__POINTER_AFTER(kbts__entry_exit, Adjust);++ kbts_glyph *Prev;+ if(kbts__NextGlyph(Storage, Lookup, CurrentGlyph->Prev, RegularSkipFlags, SkipUnicodeFlags, &Prev, 1))+ {+ // For two cursive glyphs to be aligned, they both need to be defined by the same cursive attachment table.+ kbts__cover_glyph_result PrevCover = kbts__CoverGlyph(Coverage, Prev->Id);++ if(PrevCover.Valid)+ {+ // Get anchor points for both glyphs.+ kbts__entry_exit *PrevEntryExit = &EntryExits[PrevCover.Index];+ kbts__entry_exit *EntryExit = &EntryExits[Cover.Index];++ if(PrevEntryExit->ExitAnchorOffset && EntryExit->EntryAnchorOffset)+ {+ kbts__anchor *PrevExitAnchor = KBTS__POINTER_OFFSET(kbts__anchor, Adjust, PrevEntryExit->ExitAnchorOffset);+ kbts__anchor *EntryAnchor = KBTS__POINTER_OFFSET(kbts__anchor, Adjust, EntryExit->EntryAnchorOffset);+ kbts_s32 Anchor0X = PrevExitAnchor->X;+ kbts_s32 Anchor0Y = PrevExitAnchor->Y;+ kbts_s32 Anchor1X = EntryAnchor->X;+ kbts_s32 Anchor1Y = EntryAnchor->Y;+ kbts_s32 Advance0X = Prev->AdvanceX;+ kbts_s32 Advance1X = CurrentGlyph->AdvanceX;+ kbts_s32 Offset0X = Prev->OffsetX;+ kbts_s32 Offset0Y = Prev->OffsetY;+ kbts_s32 Offset1X = CurrentGlyph->OffsetX;+ kbts_s32 Offset1Y = CurrentGlyph->OffsetY;++ // Cursive positioning is made up of two parts.+ // The first part is glyph-to-glyph alignment, which depends on the text direction.+ // Here, we are only concerned with making the relative placements of the glyphs correct,+ // insofar as they follow the specified anchor positions.+ //+ // The OpenType spec makes no attempt to describe how the two glyphs should be aligned, mathematically+ // speaking.+ //+ // This is all we get:+ //+ // "To position glyphs using the CursivePosFormat1 subtable, a text-processing client aligns the exit+ // anchor point of a glyph with the entry anchor point of the following glyph."+ //+ // In practice, we reproduce harfbuzz's behavior here, which is:+ // - Glyph1.Offset.X is unaffected+ // - Glyph1.Advance.X = Glyph1.Offset.X + Glyph1.Anchor.X, aka. the _actual position of its anchor_+ // - Glyph2.Offset.X = -Glyph2.Anchor.X+ // - Glyph2.Offset.Y = Glyph1.Anchor.Y - Glyph2.Anchor.Y+ // - Glyph2.Advance.X -= Glyph2.Anchor.X+ //+ // (...where "X" here just means "the main direction". In top-to-bottom or bottom-to-top contexts, that+ // would be the Y coordinate, but we do not support those yet.)+ //+ // So, instead of aligning everything with offsets, we use Advance to align _the rest of the string_+ // horizontally with the first glyph, and not just the next glyph.+ //+ // It might seem dumb to modify both Glyph2.Offset _and_ Glyph2.Advance, because, when the glyphs are next+ // to one another, this is equivalent to modifying Glyph1.Advance. However, due to lookup flag nonsense,+ // there may be some glyphs between Glyph1 and Glyph2, and, _apparently_, it is fine to adjust them by the+ // position of Glyph1's anchor point, and it is not fine to adjust them by the position of Glyph2's anchor+ // point.+ //+ // This Advance tweak seems like it would be wrong, because any marks attached to Glyph1 will then have+ // invalid positions. The hope is that this does not matter in practice, because 'mark' is applied after+ // 'curs', and font designers are expected to know that and to know never to apply mark attachments+ // before cursive positioning, I guess.+ if(!kbts__ShaperRtl(Config->Shaper))+ {+ Advance0X = Offset0X + Anchor0X;+ kbts_s32 Dx = -Anchor1X - Offset1X;+ Advance1X += Dx;+ Offset1X += Dx;+ }+ else+ {+ kbts_s32 Dx = -Anchor0X - Offset0X;+ Advance0X += Dx;+ Offset0X += Dx;+ Advance1X = Offset1X + Anchor1X;+ }++ Prev->AdvanceX = Advance0X;+ Prev->OffsetX = Offset0X;+ Prev->Flags |= (KBTS_GLYPH_FLAG_CURSIVE | KBTS_GLYPH_FLAG_USED_IN_GPOS | KBTS_GLYPH_FLAG_NO_BREAK);+ kbts__SetCursiveFlags(Prev, KBTS__CURSIVE_FLAG_START);+ CurrentGlyph->AdvanceX = Advance1X;+ CurrentGlyph->OffsetX = Offset1X;+ CurrentGlyph->Flags |= KBTS_GLYPH_FLAG_CURSIVE | KBTS_GLYPH_FLAG_USED_IN_GPOS;+ kbts__SetCursiveFlags(CurrentGlyph, KBTS__CURSIVE_FLAG_END);++ for(kbts_glyph *CursiveGlyph = Prev->Next;+ CursiveGlyph != CurrentGlyph;+ CursiveGlyph = CursiveGlyph->Next)+ {+ CursiveGlyph->Flags |= KBTS_GLYPH_FLAG_NO_BREAK;+ kbts__SetCursiveFlags(CursiveGlyph, 0);+ }++ // The second part is aligning the newly-formed cursive cluster to the "baseline". It is trickier than you'd expect.+ //+ // When applying cursive attachments, Glyph1 (RIGHT_TO_LEFT=0) or Glyph2 (RIGHT_TO_LEFT=1) is treated as being+ // "on the baseline" and its Y coordinate is used as the reference Y coordinate for the entire cursive glyph+ // cluster that has been formed so far.+ // This means that, anytime we apply a cursive attachment, we have to offset _all_ of the cursive glyphs to the+ // left (RIGHT_TO_LEFT=0) or to the right (RIGHT_TO_LEFT=1) of it.+ // This is obviously O(n^2), and @Speed: it might be worthwhile to record cursive offsets as we go, and only resolve+ // them when we actually need them, i.e. when applying a non-cursive lookup or, at the latest, when we are done with+ // positioning.+ //+ // The glyph being attached is set at a hard relative offset from the reference glyph. Its previous Y coordinate only+ // matters insofar as we need to align every other cursive glyph in its direction.++ kbts_s32 CursiveDy = 0;+ kbts_glyph *CursiveGlyph = CurrentGlyph;+ int Backward = 0;+ kbts_u32 AdjustNearbyGlyphs = (CurrentGlyph->Flags & KBTS_GLYPH_FLAG_CURSIVE);++ if(!(Lookup->Flags & KBTS__LOOKUP_FLAG_RIGHT_TO_LEFT))+ {+ kbts_s32 NewOffset1Y = Offset0Y + Anchor0Y - Anchor1Y;+ CursiveDy = NewOffset1Y - Offset1Y;+ }+ else+ {+ kbts_s32 NewOffset0Y = Offset1Y + Anchor1Y - Anchor0Y;+ CursiveDy = NewOffset0Y - Offset0Y;+ Backward = 1;+ CursiveGlyph = Prev;+ AdjustNearbyGlyphs = 1;+ }++ CursiveGlyph->OffsetY += CursiveDy;++ if(AdjustNearbyGlyphs)+ {+ kbts__SetCursiveFlags(CursiveGlyph, 0);+ CursiveGlyph = Backward ? CursiveGlyph->Prev : CursiveGlyph->Next;++ kbts__cursive_flags StopFlag = Backward ? KBTS__CURSIVE_FLAG_END : KBTS__CURSIVE_FLAG_START;++ while(kbts__GlyphIsValid(Storage, CursiveGlyph))+ {+ kbts__cursive_flags CursiveFlags = kbts__GetCursiveFlags(CursiveGlyph);++ if(CursiveFlags & StopFlag)+ {+ break;+ }+ else if(CursiveGlyph->Flags & KBTS_GLYPH_FLAG_CURSIVE)+ {+ CursiveGlyph->OffsetY += CursiveDy;+ }+ else if(!(CursiveGlyph->Classes.Class & KBTS__GLYPH_CLASS_MARK)) // Ignore marks.+ {+ break;+ }++ CursiveGlyph = Backward ? CursiveGlyph->Prev : CursiveGlyph->Next;+ }+ }++ Result = 1;+ }+ }+ }+ }+ break;++ case 4:+ case 6:+ {+ kbts__mark_to_base_attachment *Adjust = (kbts__mark_to_base_attachment *)Base;++ // We want to know which glyph to attach to, and how far that glyph is from us.+ // To do that, we add up all advances between it and us.+ // There is a slight wrinkle here: most shapers end up zeroing mark advances at the _end_+ // of the shaping process, which would retroactively make a naive advance accumulation wrong.+ // We have to take that into account here, and only accumulate mark advances for shapers that+ // don't do that zeroing at the end (either because they do it at the beginning of GPOS, or+ // because they don't do it at all).+ int CountMarkAdvances = !kbts__ShaperClearsMarkAdvancesInPostGposFixup(Config->Shaper);+ kbts__coverage *BaseCoverage = KBTS__POINTER_OFFSET(kbts__coverage, Adjust, Adjust->BaseCoverageOffset);+ kbts_s32 AdvanceSinceBaseX = 0;+ kbts_s32 AdvanceSinceBaseY = 0;+ kbts_u32 BaseClasses = Lookup->Type == 6 ? (1 << KBTS__GLYPH_CLASS_MARK) : (1 | (1 << KBTS__GLYPH_CLASS_BASE) | (1 << KBTS__GLYPH_CLASS_LIGATURE) | (1 << KBTS__GLYPH_CLASS_COMPONENT));+ kbts_glyph *BaseGlyph = 0;+ for(kbts_glyph *PrevGlyph = CurrentGlyph->Prev; kbts__GlyphIsValid(Storage, PrevGlyph); PrevGlyph = PrevGlyph->Prev)+ {+ if(CountMarkAdvances || (PrevGlyph->Classes.Class != KBTS__GLYPH_CLASS_MARK))+ {+ AdvanceSinceBaseX += PrevGlyph->AdvanceX;+ AdvanceSinceBaseY += PrevGlyph->AdvanceY;+ }++ if(!kbts__SkipGlyph(PrevGlyph, Lookup, RegularSkipFlags, SkipUnicodeFlags))+ {+ if((1 << PrevGlyph->Classes.Class) & BaseClasses)+ {+ // :MultipleSubstSadness+ // There is some sadness when we have to look for bases here...+ // In multiple substitutions, we allow skipping covered glyphs if they are:+ // - Not the first in the multiple substitution+ // - Not preceded by a mark+ //+ // More details on the sadness can be found here:+ // https://github.com/harfbuzz/harfbuzz/issues/740+ // https://github.com/harfbuzz/harfbuzz/issues/1020+ // https://github.com/harfbuzz/harfbuzz/issues/4124+ if((Lookup->Type == 4) &&+ ((PrevGlyph->Flags & (KBTS_GLYPH_FLAG_FIRST_IN_MULTIPLE_SUBSTITUTION | KBTS_GLYPH_FLAG_MULTIPLE_SUBSTITUTION)) == KBTS_GLYPH_FLAG_MULTIPLE_SUBSTITUTION) && // Stop if we see the first of a multiple substitution.+ (PrevGlyph->Prev->Classes.Class != KBTS__GLYPH_CLASS_MARK)) // Stop if we see any mark.+ {+ // Otherwise, we allow skipping uncovered glyphs.+ kbts__cover_glyph_result BaseCover = kbts__CoverGlyph(BaseCoverage, PrevGlyph->Id);+ if(BaseCover.Valid)+ {+ BaseGlyph = PrevGlyph;+ break;+ }+ }+ else+ {+ BaseGlyph = PrevGlyph;+ break;+ }+ }+ else if(Lookup->Type == 6)+ {+ // Unskipped non-marks block mark attachments.+ break;+ }+ }+ }++ if(BaseGlyph)+ {+ int Ok = (Lookup->Type == 4) || // This is a mark-to-base attachment+ ((BaseGlyph->LigatureUid == CurrentGlyph->LigatureUid) && (BaseGlyph->LigatureComponentIndexPlusOne == CurrentGlyph->LigatureComponentIndexPlusOne)) || // This is a mark-to-mark attachment, and both marks belong to the same ligature component+ ((BaseGlyph->Flags | CurrentGlyph->Flags) & KBTS_GLYPH_FLAG_LIGATURE); // This is a mark-to-mark attachment, and either mark was created by a ligature substitution+ if(Ok)+ {+ // @Speed: This is duplicating work in the :MultipleSubstSadness case.+ kbts__cover_glyph_result BaseCover = kbts__CoverGlyph(BaseCoverage, BaseGlyph->Id);++ if(BaseCover.Valid)+ {+ kbts__base_array *BaseArray = KBTS__POINTER_OFFSET(kbts__base_array, Adjust, Adjust->BaseArrayOffset);+ kbts_u16 *BaseAnchorOffsets = KBTS__POINTER_AFTER(kbts_u16, BaseArray) + BaseCover.Index * Adjust->MarkClassCount;+ kbts__mark_info MarkInfo = kbts__GetMarkInfo(Adjust, Adjust->MarkArrayOffset, Cover.Index);++ kbts_u16 BaseAnchorOffset = BaseAnchorOffsets[MarkInfo.Record->Class];+ if(BaseAnchorOffset)+ {+ kbts__anchor *BaseAnchor = KBTS__POINTER_OFFSET(kbts__anchor, BaseArray, BaseAnchorOffset);++ /* From the Microsoft docs:+ When a mark is combined with a given base, the mark placement is adjusted so that the mark anchor is+ aligned with the base anchor for the applicable mark class. Placement of the base glyph and advances of+ both glyphs are not affected.+ */++ kbts_s32 NewOffsetX = BaseGlyph->OffsetX - AdvanceSinceBaseX + (BaseAnchor->X - MarkInfo.Anchor->X);+ kbts_s32 NewOffsetY = BaseGlyph->OffsetY - AdvanceSinceBaseY + (BaseAnchor->Y - MarkInfo.Anchor->Y);++ kbts__AttachGlyph(Storage, BaseGlyph, CurrentGlyph, NewOffsetX, NewOffsetY);++ Result = 1;+ }+ }+ }+ }+ }+ break;++ case 5:+ {+ kbts__mark_to_ligature_attachment *Adjust = (kbts__mark_to_ligature_attachment *)Base;++ kbts_s32 AdvanceSinceBaseX = 0;+ kbts_s32 AdvanceSinceBaseY = 0;+ kbts_u32 BaseClasses = (1 | (1 << KBTS__GLYPH_CLASS_BASE) | (1 << KBTS__GLYPH_CLASS_LIGATURE) | (1 << KBTS__GLYPH_CLASS_COMPONENT));+ kbts_glyph *LigatureGlyph = 0;+ for(kbts_glyph *PrevGlyph = CurrentGlyph->Prev;+ kbts__GlyphIsValid(Storage, PrevGlyph);+ PrevGlyph = PrevGlyph->Prev)+ {+ AdvanceSinceBaseX += PrevGlyph->AdvanceX;+ AdvanceSinceBaseY += PrevGlyph->AdvanceY;+ if(!kbts__SkipGlyph(PrevGlyph, Lookup, RegularSkipFlags, SkipUnicodeFlags) && ((1 << PrevGlyph->Classes.Class) & BaseClasses))+ {+ LigatureGlyph = PrevGlyph;+ break;+ }+ }++ if(LigatureGlyph)+ {+ kbts__cover_glyph_result LigatureCover = kbts__CoverGlyph(KBTS__POINTER_OFFSET(kbts__coverage, Adjust, Adjust->LigatureCoverageOffset),+ LigatureGlyph->Id);+ if(LigatureCover.Valid)+ {+ kbts__ligature_array *LigatureArray = KBTS__POINTER_OFFSET(kbts__ligature_array, Adjust, Adjust->LigatureArrayOffset);+ kbts__ligature_attach *LigatureAttach = kbts__GetLigatureAttach(LigatureArray, LigatureCover.Index);+ kbts__mark_info MarkInfo = kbts__GetMarkInfo(Adjust, Adjust->MarkArrayOffset, Cover.Index);+ kbts_un LigatureComponentIndexPlusOne = CurrentGlyph->LigatureComponentIndexPlusOne;++ if(CurrentGlyph->LigatureUid != LigatureGlyph->Uid)+ {+ // If the mark is not yet attached to the ligature, attach it now.+ // Apparently, in this case, the mark should be considered part of the _last_ component of the ligature.+ LigatureComponentIndexPlusOne = LigatureAttach->Count;+ }++ if(LigatureComponentIndexPlusOne <= LigatureAttach->Count)+ {+ kbts_un AnchorIndex = LigatureComponentIndexPlusOne;+ if(AnchorIndex)+ {+ AnchorIndex -= 1;+ }+ else+ {+ AnchorIndex = LigatureAttach->Count - 1;+ }++ kbts__anchor *LigatureAnchor = kbts__GetLigatureAttachAnchor(Adjust, LigatureAttach, MarkInfo.Record->Class, AnchorIndex);++ kbts_s32 NewOffsetX = LigatureGlyph->OffsetX - AdvanceSinceBaseX + (LigatureAnchor->X - MarkInfo.Anchor->X);+ kbts_s32 NewOffsetY = LigatureGlyph->OffsetY - AdvanceSinceBaseY + (LigatureAnchor->Y - MarkInfo.Anchor->Y);++ kbts__AttachGlyph(Storage, LigatureGlyph, CurrentGlyph, NewOffsetX, NewOffsetY);++ CurrentGlyph->LigatureComponentIndexPlusOne = (kbts_u16)LigatureComponentIndexPlusOne;+ CurrentGlyph->LigatureUid = LigatureGlyph->Uid;+ // I'm not sure why, but Harfbuzz only clears this in mark-to-ligature substitutions, and not in mark-to-base or+ // mark-to-mark.+ CurrentGlyph->AdvanceX = 0;+ CurrentGlyph->AdvanceY = 0;++ for(kbts_glyph *MiddleGlyph = LigatureGlyph->Next;+ MiddleGlyph != CurrentGlyph;+ MiddleGlyph = MiddleGlyph->Next)+ {+ MiddleGlyph->Flags |= KBTS_GLYPH_FLAG_NO_BREAK;+ }++ Result = 1;+ }+ }+ }+ }+ break;++ case 7:+ case 8:+ {+ kbts__sequence_lookup_result SequenceLookup = kbts__DoSequenceLookup(Storage, Lookup, Base, Cover, CurrentGlyph, SequenceSkipFlags, SkipUnicodeFlags);+ if(SequenceLookup.RecordCount)+ {+ KBTS__FOR(RecordIndex, 0, SequenceLookup.RecordCount)+ {+ kbts__sequence_lookup_record *Record = &SequenceLookup.Records[RecordIndex];+ kbts__lookup *PackedRecordLookup = kbts__GetLookup(LookupList, Record->LookupListIndex);+ kbts__unpacked_lookup RecordLookup = kbts__UnpackLookup(kbts__BlobTableDataType(Config->Font->Blob, KBTS_BLOB_TABLE_ID_GDEF, kbts__gdef), PackedRecordLookup);++ kbts_glyph *NestedCurrentGlyph = CurrentGlyph;+ kbts_un NestedCurrentGlyphIndex = 0;+ { // Figure out where in the input sequence we need to apply the lookup.+ kbts_un SequenceIndex = 0;+ for(kbts_glyph *Glyph = CurrentGlyph;+ kbts__GlyphIsValid(Storage, Glyph);+ Glyph = Glyph->Next)+ {+ if(!kbts__SkipGlyph(Glyph, Lookup, SequenceSkipFlags, SkipUnicodeFlags))+ {+ if(SequenceIndex == Record->SequenceIndex)+ {+ NestedCurrentGlyph = Glyph;++ break;+ }++ SequenceIndex += 1;+ }++ NestedCurrentGlyphIndex += 1;+ }+ }++ KBTS__FOR(NestedSubtableIndex, 0, RecordLookup.SubtableCount)+ {+ kbts_u16 *NestedBase = KBTS__POINTER_OFFSET(kbts_u16, PackedRecordLookup, RecordLookup.SubtableOffsets[NestedSubtableIndex]);++ kbts__DoSingleAdjustment(Scratchpad, Config, Storage, LookupList,+ Record->LookupListIndex, NestedSubtableIndex, &RecordLookup, NestedBase,+ NestedCurrentGlyph, StartIndex + NestedCurrentGlyphIndex, RequestedSkipFlags);+ }+ }++ OnePastLastGlyphIndex = StartIndex + SequenceLookup.InputSequenceCountIncludingSkippedGlyphs;+ OnePastLastGlyph = SequenceLookup.OnePastLastGlyphMatched;+ }+ }+ break;+ }++ kbts__SetLookupOnePastLastGlyph(Scratchpad, OnePastLastGlyphIndex + OnePastLastGlyphOffset, OnePastLastGlyph);+ }++ Lookup->Type = OriginalLookupType;+ }++ KBTS_INSTRUMENT_FUNCTION_END;+ return Result;+}++typedef kbts_u32 kbts__mcm_sequence_state;+enum kbts__mcm_sequence_state_enum+{+ KBTS__MCM_SEQUENCE_STATE_NONE,+ KBTS__MCM_SEQUENCE_STATE_OUT,+ KBTS__MCM_SEQUENCE_STATE_IN,+};++typedef kbts_u32 kbts__hangul_syllable_type;+enum kbts__hangul_syllable_type_enum+{+ KBTS__HANGUL_SYLLABLE_TYPE_NONE,++ KBTS__HANGUL_SYLLABLE_TYPE_L,+ KBTS__HANGUL_SYLLABLE_TYPE_V,+ KBTS__HANGUL_SYLLABLE_TYPE_T,+ KBTS__HANGUL_SYLLABLE_TYPE_LV,+ KBTS__HANGUL_SYLLABLE_TYPE_LVT,++ KBTS__HANGUL_SYLLABLE_TYPE_COUNT,+};++typedef struct kbts__hangul_syllable_info+{+ kbts__hangul_syllable_type Type;+ kbts_u32 Composable;+} kbts__hangul_syllable_info;++static kbts__hangul_syllable_info kbts__HangulSyllableInfo(kbts_u32 Codepoint)+{+ kbts__hangul_syllable_info Result = KBTS__ZERO;++ if((Codepoint >= 0x1100) && (Codepoint <= 0x115F))+ {+ Result.Type = KBTS__HANGUL_SYLLABLE_TYPE_L;+ Result.Composable = (Codepoint < 0x1113);+ }+ else if((Codepoint >= 0x1160) && (Codepoint <= 0x11A7))+ {+ Result.Type = KBTS__HANGUL_SYLLABLE_TYPE_V;+ Result.Composable = ((Codepoint >= 0x1161) & (Codepoint <= 0x1175));+ }+ else if((Codepoint >= 0x11A8) && (Codepoint <= 0x11FF))+ {+ Result.Type = KBTS__HANGUL_SYLLABLE_TYPE_T;+ Result.Composable = (Codepoint < 0x11C3);+ }+ else if((Codepoint >= 0xA960) && (Codepoint <= 0xA97C))+ {+ Result.Type = KBTS__HANGUL_SYLLABLE_TYPE_L;+ }+ else if((Codepoint == 0xAC00) && (Codepoint <= 0xD7A3))+ {+ Result.Type = KBTS__HANGUL_SYLLABLE_TYPE_LVT;++ if(!((Codepoint - 0xAC00) % 28))+ {+ Result.Type = KBTS__HANGUL_SYLLABLE_TYPE_LV;+ }+ }+ else if((Codepoint >= 0xD7B0) && (Codepoint <= 0xD7C6))+ {+ Result.Type = KBTS__HANGUL_SYLLABLE_TYPE_V;+ }+ else if((Codepoint >= 0xD7CB) && (Codepoint <= 0xD7FB))+ {+ Result.Type = KBTS__HANGUL_SYLLABLE_TYPE_T;+ }++ return Result;+}++KBTS_INLINE kbts_u32 kbts__SyllabicClassIsConsonant(kbts_indic_syllabic_class Class)+{+ kbts_u32 Result =+ KBTS__IN_SET(Class, KBTS__SET32((KBTS_INDIC_SYLLABIC_CLASS_CONSONANT)(KBTS_INDIC_SYLLABIC_CLASS_RA)(KBTS_INDIC_SYLLABIC_CLASS_CONSONANT_WITH_STACKER)(KBTS_INDIC_SYLLABIC_CLASS_CONSONANT_MEDIAL)));+ return Result;+}++enum+{+ KBTS__FEATURE_MATCH_FLAG_KA_JA = (1 << 0),+ KBTS__FEATURE_MATCH_FLAG_SSA_NYA = (1 << 1),+ KBTS__FEATURE_MATCH_FLAG_RA_HA_VA = (1 << 2),+ KBTS__FEATURE_MATCH_FLAG_YA = (1 << 3),+ KBTS__FEATURE_MATCH_FLAG_CONSONANT = (1 << 4),+ KBTS__FEATURE_MATCH_FLAG_NUKTA = (1 << 5),+ KBTS__FEATURE_MATCH_FLAG_HALANT = (1 << 6),+ KBTS__FEATURE_MATCH_FLAG_ZWJ = (1 << 7),+ KBTS__FEATURE_MATCH_FLAG_ZWNJ = (1 << 8),+ KBTS__FEATURE_MATCH_FLAG_INITIAL = (1 << 10),+ KBTS__FEATURE_MATCH_FLAG_POST_BASE = (1 << 11),++ KBTS__FEATURE_MATCH_FLAG_RPHF = KBTS__FEATURE_FLAG0(rphf),+};+# define KBTS__FEATURE_MATCH_MASK(W0, W1, W2, W3) (((kbts_u64)(W0) << 48) | ((kbts_u64)(W1) << 32) | ((kbts_u64)(W0) << 16) | (kbts_u64)(W0))+# define KBTS__FEATURE_MATCH_MASK_AKHN KBTS__FEATURE_MATCH_MASK(0, KBTS__FEATURE_MATCH_FLAG_KA_JA, KBTS__FEATURE_MATCH_FLAG_HALANT, KBTS__FEATURE_MATCH_FLAG_SSA_NYA)+# define KBTS__FEATURE_MATCH_MASK_BLWF_PRE KBTS__FEATURE_MATCH_MASK(0, 0, KBTS__FEATURE_MATCH_FLAG_RA_HA_VA | KBTS__FEATURE_MATCH_FLAG_INITIAL, KBTS__FEATURE_MATCH_FLAG_HALANT)+# define KBTS__FEATURE_MATCH_MASK_BLWF_PRE_OK KBTS__FEATURE_MATCH_MASK(0, 0, KBTS__FEATURE_MATCH_FLAG_RA_HA_VA, KBTS__FEATURE_MATCH_FLAG_HALANT)+# define KBTS__FEATURE_MATCH_MASK_BLWF_POST KBTS__FEATURE_MATCH_MASK(0, 0, KBTS__FEATURE_MATCH_FLAG_HALANT, KBTS__FEATURE_MATCH_FLAG_RA_HA_VA)+# define KBTS__FEATURE_MATCH_MASK_CJCT KBTS__FEATURE_MATCH_MASK(0, KBTS__FEATURE_MATCH_FLAG_CONSONANT, KBTS__FEATURE_MATCH_FLAG_HALANT, KBTS__FEATURE_MATCH_FLAG_CONSONANT)+# define KBTS__FEATURE_MATCH_MASK_HALF KBTS__FEATURE_MATCH_MASK(KBTS__FEATURE_MATCH_FLAG_CONSONANT | KBTS__FEATURE_MATCH_FLAG_RPHF | KBTS__FEATURE_MATCH_FLAG_POST_BASE, KBTS__FEATURE_MATCH_FLAG_HALANT, KBTS__FEATURE_MATCH_FLAG_ZWNJ, KBTS__FEATURE_MATCH_FLAG_CONSONANT)+# define KBTS__FEATURE_MATCH_MASK_HALF_OK KBTS__FEATURE_MATCH_MASK(KBTS__FEATURE_MATCH_FLAG_CONSONANT, KBTS__FEATURE_MATCH_FLAG_HALANT, 0, 0)+# define KBTS__FEATURE_MATCH_MASK_NUKT KBTS__FEATURE_MATCH_MASK(0, 0, KBTS__FEATURE_MATCH_FLAG_CONSONANT, KBTS__FEATURE_MATCH_FLAG_HALANT)+# define KBTS__FEATURE_MATCH_MASK_PSTF KBTS__FEATURE_MATCH_MASK(0, 0, KBTS__FEATURE_MATCH_FLAG_HALANT | KBTS__FEATURE_MATCH_FLAG_INITIAL, KBTS__FEATURE_MATCH_FLAG_YA)+# define KBTS__FEATURE_MATCH_MASK_VATU KBTS__FEATURE_MATCH_MASK(0, KBTS__FEATURE_MATCH_FLAG_CONSONANT, KBTS__FEATURE_MATCH_FLAG_HALANT, KBTS__FEATURE_MATCH_FLAG_RA_HA_VA)++typedef kbts_u32 kbts__substitution_result_flags;+enum kbts__substitution_result_flags_enum+{+ KBTS__SUBSTITUTION_RESULT_FLAG_MATCHED_SUBSTITUTION = (1 << 0),+ KBTS__SUBSTITUTION_RESULT_FLAG_TRIED_TO_INSERT_WHILE_CHECK_ONLY = (1 << 1),+};++static void kbts__BeginLookupApplication(kbts__shape_scratchpad *Scratchpad, kbts_glyph *Glyph)+{+ Scratchpad->LookupOnePastLastGlyph = Glyph->Next;+ Scratchpad->LookupOnePastLastGlyphIndex = 0;+}++static kbts_glyph *kbts__EndLookupApplication(kbts__shape_scratchpad *Scratchpad)+{+ kbts_glyph *Result = Scratchpad->LookupOnePastLastGlyph;+ return Result;+}++static kbts__substitution_result_flags kbts__DoSubstitution(kbts__shape_scratchpad *Scratchpad, kbts_shape_config *Config, kbts_glyph_storage *Storage,+ kbts_lookup_list *LookupList, kbts__gsub_frame *Frames, kbts_un *FrameCount_,+ int CheckOnly, kbts__skip_flags RequestedSkipFlags, kbts_u32 GeneratedGlyphFlags)+{+ kbts__substitution_result_flags Result = 0;+ kbts_font *Font = Config->Font;+ kbts_unicode_flags SkipUnicodeFlags = 0; // @Incomplete+ kbts__skip_flags RegularSkipFlags = KBTS__SKIP_FLAGS_GSUB_REGULAR(RequestedSkipFlags);+ kbts__skip_flags SequenceSkipFlags = KBTS__SKIP_FLAGS_GSUB_SEQUENCE(RequestedSkipFlags);+ GeneratedGlyphFlags |= KBTS_GLYPH_FLAG_GENERATED_BY_GSUB;++ kbts_un FrameCount = *FrameCount_;+ kbts__gsub_frame *Frame = &Frames[FrameCount - 1];++ kbts__lookup *PackedLookup = kbts__GetLookup(LookupList, Frame->LookupIndex);+ kbts__unpacked_lookup Lookup = kbts__UnpackLookup(kbts__BlobTableDataType(Font->Blob, KBTS_BLOB_TABLE_ID_GDEF, kbts__gdef), PackedLookup);+ kbts_u16 BaseLookupType = Lookup.Type;++ while(Frame->SubtableIndex < Lookup.SubtableCount)+ {+ kbts_u16 *Subtable = KBTS__POINTER_OFFSET(kbts_u16, PackedLookup, Lookup.SubtableOffsets[Frame->SubtableIndex]);+ // In a type-7 lookup, each subtable can specify a different lookup type.+ // We still want to pass kbts__unpacked_lookup around as a useful bag of arguments, though.+ // So, we restore the original lookup's type here before resolving each subtable.+ Lookup.Type = BaseLookupType;++ while(Lookup.Type == 7)+ {+ kbts__extension *Extension = (kbts__extension *)Subtable;+ Lookup.Type = Extension->LookupType;+ Subtable = KBTS__POINTER_OFFSET(kbts_u16, Extension, Extension->Offset);+ }++ kbts_glyph *CurrentGlyph = Frame->InputGlyph;++ kbts__skip_flags SkipFlags = (Lookup.Type >= 5) ? SequenceSkipFlags : RegularSkipFlags;+ if(kbts__GlyphsIncludedInLookupSubtable(Storage, Font, 0, &Lookup, Frame->LookupIndex, Frame->SubtableIndex, CurrentGlyph, SkipFlags, SkipUnicodeFlags))+ {+ kbts__cover_glyph_result Cover = KBTS__ZERO;+ Cover.Valid = kbts__GlyphPassesLookupFilter(CurrentGlyph, &Lookup);+ if(Cover.Valid && kbts__GsubLookupBeginsWithCoverage(Lookup.Type, Subtable[0]))+ {+ kbts__coverage *Coverage = KBTS__POINTER_OFFSET(kbts__coverage, Subtable, Subtable[1]);+ Cover = kbts__CoverGlyph(Coverage, CurrentGlyph->Id);+ }++ if(Cover.Valid)+ {+ kbts_un OnePastLastGlyphOffset = 1;+ kbts_glyph *OnePastLastGlyph = CurrentGlyph->Next;++ if((Lookup.Type == 5) || (Lookup.Type == 6))+ {+ kbts__sequence_lookup_result SequenceLookup = kbts__DoSequenceLookup(Storage, &Lookup, Subtable, Cover, CurrentGlyph, SequenceSkipFlags, SkipUnicodeFlags);++ if(SequenceLookup.Matched)+ {+ Frame->Records = SequenceLookup.Records;+ Frame->RecordCount = (kbts_u16)SequenceLookup.RecordCount;+ Frame->RecordIndex = 0;++ Frame->SubtableIndex = 0xFFFE;++ OnePastLastGlyphOffset = SequenceLookup.InputSequenceCountIncludingSkippedGlyphs;+ OnePastLastGlyph = SequenceLookup.OnePastLastGlyphMatched;+ }+ }+ else+ {+ // Do single substitution.++ switch(Lookup.Type)+ {+ case 1:+ {+ Result |= KBTS__SUBSTITUTION_RESULT_FLAG_MATCHED_SUBSTITUTION;++ if(!CheckOnly)+ {+ kbts__single_substitution *Subst = (kbts__single_substitution *)Subtable;++ kbts_u16 NewId = 0;+ if(Subst->Format == 1)+ {+ // From the Microsoft docs:+ // "Addition of deltaGlyphID is modulo 65536."+ NewId = (CurrentGlyph->Id + (kbts_u32)Subst->DeltaOrCount.DeltaGlyphId) & 0xFFFF;+ }+ else if(Subst->Format == 2)+ {+ kbts_u16 *SubstituteGlyphIds = KBTS__POINTER_AFTER(kbts_u16, Subst);+ NewId = SubstituteGlyphIds[Cover.Index];+ }++ kbts__GsubMutate(Font, CurrentGlyph, NewId, GeneratedGlyphFlags);+ }+ } break;++ case 2:+ {+ kbts__multiple_substitution *Subst = (kbts__multiple_substitution *)Subtable;+ kbts__sequence *Sequence = kbts__GetSequence(Subst, Cover.Index);+ Result |= KBTS__SUBSTITUTION_RESULT_FLAG_MATCHED_SUBSTITUTION;++ if(!CheckOnly)+ {+ kbts_u16 *SubstGlyphIds = KBTS__POINTER_AFTER(kbts_u16, Sequence);++ kbts_un GrowCount = Sequence->GlyphCount - 1;++ if(Sequence->GlyphCount)+ {+ kbts_glyph OriginalGlyph = *CurrentGlyph;+ kbts_glyph *LastInsert = CurrentGlyph;+ KBTS__FOR(SubstGlyphIndex, 0, Sequence->GlyphCount)+ {+ kbts_u32 NewGlyphFlags = GeneratedGlyphFlags | KBTS_GLYPH_FLAG_MULTIPLE_SUBSTITUTION;++ kbts_glyph *NewGlyph = CurrentGlyph;+ if(SubstGlyphIndex)+ {+ NewGlyph = kbts__InsertGlyphAfter(Storage, LastInsert, &OriginalGlyph);++ if(!NewGlyph)+ {+ Scratchpad->Error = KBTS_SHAPE_ERROR_OUT_OF_MEMORY;+ return Result;+ }++ NewGlyph->Uid = (kbts_u16)++Scratchpad->NextGlyphUid;+ }+ else+ {+ NewGlyphFlags |= KBTS_GLYPH_FLAG_FIRST_IN_MULTIPLE_SUBSTITUTION;+ }++ kbts__GsubMutate(Font, NewGlyph, SubstGlyphIds[SubstGlyphIndex], GeneratedGlyphFlags | NewGlyphFlags);++ LastInsert = NewGlyph;+ }++ OnePastLastGlyph = LastInsert->Next;+ }+ else+ {+ kbts__FreeGlyph(Scratchpad, Storage, CurrentGlyph);+ }++ OnePastLastGlyphOffset = 1 + GrowCount;++ // Shift other frames' input cursors.+ KBTS__FOR(FrameIndex, 0, FrameCount - 1)+ {+ kbts__gsub_frame *OtherFrame = &Frames[FrameIndex];++ if(OtherFrame->StartIndex > Frame->StartIndex)+ {+ OtherFrame->StartIndex = (kbts_u16)(OtherFrame->StartIndex + GrowCount);+ }+ }+ }+ else if(Sequence->GlyphCount > 1)+ {+ Result |= KBTS__SUBSTITUTION_RESULT_FLAG_TRIED_TO_INSERT_WHILE_CHECK_ONLY;+ }+ } break;++ case 3:+ {+ Result |= KBTS__SUBSTITUTION_RESULT_FLAG_MATCHED_SUBSTITUTION;++ if(!CheckOnly)+ {+ kbts__alternate_substitution *Subst = (kbts__alternate_substitution *)Subtable;+ kbts__alternate_set *Set = kbts__GetAlternateSet(Subst, Cover.Index);+ kbts_u16 *AltGlyphIds = KBTS__POINTER_AFTER(kbts_u16, Set);++ kbts_un AlternateIndex = 0;++ {+ kbts__feature_set *ShaperFeatures = &Config->Features;+ kbts_glyph_config *GlyphConfig = CurrentGlyph->Config;+ if(GlyphConfig)+ {+ int HasOverride = 0;+ KBTS__FOR(WordIndex, 0, KBTS__ARRAY_LENGTH(GlyphConfig->EnabledFeatures.Flags))+ {+ kbts_u64 Flags = GlyphConfig->EnabledFeatures.Flags[WordIndex] & ShaperFeatures->Flags[WordIndex];+ if(Flags)+ {+ HasOverride = 1;+ break;+ }+ }++ if(HasOverride)+ {+ for(kbts__feature_override_header *OverrideHeader = GlyphConfig->FeatureOverrideSentinel.Next;+ OverrideHeader != &GlyphConfig->FeatureOverrideSentinel;+ OverrideHeader = OverrideHeader->Next)+ {+ kbts__feature_override *Override = (kbts__feature_override *)OverrideHeader;+ int Value = Override->Value;+ kbts__feature_id Id = kbts__FeatureTagToId(Override->Tag);++ if(Value &&+ kbts__ContainsFeature(&Scratchpad->LookupFeatures, Id))+ {+ int Match = 1;+ if(!Id)+ {+ // Slow path for unregistered features.+ Match = 0;+ KBTS__FOR(UnregisteredFeatureIndex, 0, Scratchpad->UnregisteredFeatureCount)+ {+ if(Override->Tag == Scratchpad->UnregisteredFeatureTags[UnregisteredFeatureIndex])+ {+ Match = 1;+ break;+ }+ }+ }++ if(Match)+ {+ AlternateIndex = (kbts_un)(Value - 1);++ break;+ }+ }+ }+ }+ }+ }++ if(AlternateIndex >= Set->GlyphCount)+ {+ AlternateIndex = 0;+ }++ kbts_u16 NewId = AltGlyphIds[AlternateIndex];+ kbts__GsubMutate(Font, CurrentGlyph, NewId, GeneratedGlyphFlags);+ }+ } break;++ case 4:+ {+ KBTS_INSTRUMENT_BLOCK_BEGIN(GSUB_Ligature);++ kbts__ligature_substitution *Subst = (kbts__ligature_substitution *)Subtable;+ kbts__ligature_set *Set = kbts__GetLigatureSet(Subst, Cover.Index);++ KBTS__FOR(LigatureIndex, 0, Set->Count)+ {+ kbts__ligature *Ligature = kbts__GetLigature(Set, LigatureIndex);+ kbts_u16 *ComponentIds = KBTS__POINTER_AFTER(kbts_u16, Ligature);+ kbts_un ComponentCount = Ligature->ComponentCount;++ kbts_un MatchingGlyphCount = 1;++ {+ kbts_glyph *LigatureGlyphCursor = CurrentGlyph->Next;+ while(kbts__GlyphIsValid(Storage, LigatureGlyphCursor) &&+ (MatchingGlyphCount < Ligature->ComponentCount))+ {+ // A ligature may contain an explicit ZWJ, which SkipGlyph() would probably skip.+ // The expected behavior in that case is to assume the font designer knows what they are doing+ // and match the ZWJ.+ if(LigatureGlyphCursor->Id == ComponentIds[MatchingGlyphCount - 1])+ {+ MatchingGlyphCount += 1;+ }+ else if(!kbts__SkipGlyph(LigatureGlyphCursor, &Lookup, RegularSkipFlags, SkipUnicodeFlags))+ {+ break;+ }++ LigatureGlyphCursor = LigatureGlyphCursor->Next;+ }+ }++ if(MatchingGlyphCount == ComponentCount)+ {+ Result |= KBTS__SUBSTITUTION_RESULT_FLAG_MATCHED_SUBSTITUTION;++ if(!CheckOnly)+ {+ kbts_u32 LigatureUid = ++Scratchpad->NextGlyphUid;++ { // For glyphs that aren't part of the ligature, store which component it is attached to.+ // For glyphs that _are_, eat them.+ kbts_un LigatureGlyphCount = 1;+ kbts_un GrowCount = 0;++ // Consider this example:+ // ABCD -> DB (A and C form a ligature)+ // DB -> DEB (E is inserted in whatever way)+ // DEB -> FB (D and E form a ligature)+ // In that case, 'B' was supposed to be attached to D, but D does not exist anymore.+ // To handle this case, we go through the ligature, counting the total flattened components+ // and the ligature info of the last glyph that is part of the ligature.+ // Then, all trailing marks get are re-attached to the new ligature, and their component indices+ // are adjusted to take into account the new (flattened) component count.+ // (I say 'flattened' here because a previous ligature glyph counts as multiple components.)+ kbts_un PreviousLigatureUid = CurrentGlyph->LigatureUid;+ kbts_un PreviousComponentCount = CurrentGlyph->LigatureComponentCount;+ if(!PreviousComponentCount)+ {+ PreviousComponentCount = 1;+ }+ kbts_un RunningComponentCount = PreviousComponentCount;++ kbts_glyph *LigatureGlyphCursor = CurrentGlyph->Next;+ while(kbts__GlyphIsValid(Storage, LigatureGlyphCursor) && (LigatureGlyphCount < ComponentCount))+ {+ kbts_glyph *Next = LigatureGlyphCursor->Next;++ if(LigatureGlyphCursor->Id == ComponentIds[LigatureGlyphCount - 1])+ {+ PreviousLigatureUid = LigatureGlyphCursor->LigatureUid;+ PreviousComponentCount = LigatureGlyphCursor->LigatureComponentCount;+ if(!PreviousComponentCount)+ {+ PreviousComponentCount = 1;+ }+ RunningComponentCount += PreviousComponentCount;++ LigatureGlyphCount += 1;++ // Eat!+ kbts__FreeGlyph(Scratchpad, Storage, LigatureGlyphCursor);+ GrowCount -= 1;+ }+ else if(kbts__SkipGlyph(LigatureGlyphCursor, &Lookup, RegularSkipFlags, SkipUnicodeFlags))+ {+ LigatureGlyphCursor->LigatureComponentIndexPlusOne = (kbts_u16)LigatureGlyphCount;+ LigatureGlyphCursor->LigatureUid = (kbts_u16)LigatureUid;+ LigatureGlyphCursor->LigatureComponentCount = (kbts_u16)ComponentCount;+ }+ else+ {+ break;+ }++ LigatureGlyphCursor = Next;+ }++ OnePastLastGlyph = CurrentGlyph->Next;++ // Re-attach trailing marks that were part of a component ligature to the new ligature.+ if(PreviousLigatureUid)+ {+ kbts_un DeltaComponentCount = RunningComponentCount - PreviousComponentCount;++ while(kbts__GlyphIsValid(Storage, LigatureGlyphCursor))+ {+ kbts_un PreviousComponentIndexPlusOne = LigatureGlyphCursor->LigatureComponentIndexPlusOne;++ if((LigatureGlyphCursor->Classes.Class == KBTS__GLYPH_CLASS_MARK) &&+ (LigatureGlyphCursor->LigatureUid == PreviousLigatureUid) &&+ PreviousComponentIndexPlusOne)+ {+ if(PreviousComponentIndexPlusOne > PreviousComponentCount)+ {+ PreviousComponentIndexPlusOne = PreviousComponentCount;+ }++ kbts_un NewComponentIndexPlusOne = PreviousComponentIndexPlusOne + DeltaComponentCount;++ LigatureGlyphCursor->LigatureUid = (kbts_u16)LigatureUid;+ LigatureGlyphCursor->LigatureComponentIndexPlusOne = (kbts_u16)NewComponentIndexPlusOne;+ }+ else+ {+ break;+ }++ LigatureGlyphCursor = LigatureGlyphCursor->Next;+ }+ }++ // Update frame input cursors.+ KBTS__FOR(FrameIndex, 0, FrameCount - 1)+ {+ kbts__gsub_frame *OtherFrame = &Frames[FrameIndex];++ if(OtherFrame->StartIndex >= Frame->StartIndex)+ {+ OtherFrame->StartIndex += (kbts_u16)GrowCount;+ }+ }+ }++ // Currently, we only take the main glyph's config into account while making the ligature's config.+ // Maybe we should merge all of the components' configs into one instead?+ kbts__GsubMutate(Font, CurrentGlyph, Ligature->Glyph, GeneratedGlyphFlags | KBTS_GLYPH_FLAG_LIGATURE);+ CurrentGlyph->Uid = (kbts_u16)LigatureUid;+ CurrentGlyph->LigatureUid = (kbts_u16)LigatureUid;+ CurrentGlyph->LigatureComponentCount = (kbts_u16)ComponentCount;++ // Harfbuzz does this, because Uniscribe does this, and so we do the same. Sigh.+ CurrentGlyph->Flags &= ~KBTS_GLYPH_FLAG_MULTIPLE_SUBSTITUTION;+ }++ break;+ }+ }++ KBTS_INSTRUMENT_BLOCK_END(GSUB_Ligature);+ } break;++ case 8:+ {+ kbts__reverse_chain_substitution *Subst = (kbts__reverse_chain_substitution *)Subtable;+ kbts__unpacked_reverse_chain_substitution Unpacked = kbts__UnpackReverseChainSubstitution(Subst, 0);++ // :BoundsChecking+ if(Cover.Index < Unpacked.GlyphCount)+ {+ // Should we use regular or sequence skip flags here?+ kbts__sequence_match BacktrackMatch = kbts__MatchCoverageSequence(Storage, &Lookup, RegularSkipFlags, SkipUnicodeFlags, Subst, Unpacked.BacktrackCoverageOffsets, Unpacked.BacktrackCount,+ CurrentGlyph->Prev, 1);+ kbts__sequence_match LookaheadMatch = kbts__MatchCoverageSequence(Storage, &Lookup, RegularSkipFlags, SkipUnicodeFlags, Subst, Unpacked.LookaheadCoverageOffsets, Unpacked.LookaheadCount,+ CurrentGlyph->Next, 0);+ if((BacktrackMatch.MatchCount == Unpacked.BacktrackCount) && (LookaheadMatch.MatchCount == Unpacked.LookaheadCount))+ {+ Result |= KBTS__SUBSTITUTION_RESULT_FLAG_MATCHED_SUBSTITUTION;+ kbts__GsubMutate(Font, CurrentGlyph, Unpacked.SubstituteGlyphIds[Cover.Index], GeneratedGlyphFlags);+ }+ }+ } break;+ }++ if(Result & KBTS__SUBSTITUTION_RESULT_FLAG_MATCHED_SUBSTITUTION)+ {+ Frame->SubtableIndex = 0xFFFE;++ // From the Microsoft docs:+ // To move to the “next” glyph, the client skips all the glyphs that participated in the lookup operation:+ // glyphs that were substituted/positioned as well as any other glyphs in the matched input sequence.+ }+ }++ kbts__SetLookupOnePastLastGlyph(Scratchpad, Frame->StartIndex + OnePastLastGlyphOffset, OnePastLastGlyph);+ }+ }++ Frame->SubtableIndex += 1;+ }++ if(Frame->RecordIndex < Frame->RecordCount)+ {+ kbts__sequence_lookup_record *SequenceRecord = &Frame->Records[Frame->RecordIndex++];++ if(FrameCount < KBTS_LOOKUP_STACK_SIZE)+ {+ kbts__gsub_frame NewFrame = KBTS__ZERO;+ NewFrame.LookupIndex = SequenceRecord->LookupListIndex;+ NewFrame.StartIndex = Frame->StartIndex;+ NewFrame.InputGlyph = Frame->InputGlyph;++ if(SequenceRecord->SequenceIndex)+ {+ // @Speed: Re-scan the sequence to find where we are in the _filtered_ sequence.+ kbts_un SequenceInputIndex = 0;+ for(kbts_glyph *FilterGlyph = Frame->InputGlyph->Next;+ kbts__GlyphIsValid(Storage, FilterGlyph);+ FilterGlyph = FilterGlyph->Next)+ {+ // @Incomplete: SequenceSkipFlags? 0?+ // What do we use here?+ if(!kbts__SkipGlyph(FilterGlyph, &Lookup, 0, SkipUnicodeFlags))+ {+ SequenceInputIndex += 1;++ if(SequenceInputIndex == SequenceRecord->SequenceIndex)+ {+ NewFrame.InputGlyph = FilterGlyph;++ break;+ }+ }++ NewFrame.StartIndex += 1;+ }+ }++ Frames[FrameCount++] = NewFrame;+ }+ }++ // Only actually pop the frame if we haven't pushed anything else in the meantime.+ if(Frame == &Frames[FrameCount - 1])+ {+ FrameCount -= 1;+ }++ *FrameCount_ = FrameCount;++ return Result;+}++static kbts__glyph_list kbts__PushGlyphList(kbts_glyph_storage *Storage, kbts_glyph *First, kbts_glyph *Last)+{+ kbts__glyph_list Result = KBTS__ZERO;++ Result.SentinelPrev = Storage->GlyphSentinel.Prev;+ Result.SentinelNext = Storage->GlyphSentinel.Next;+ Result.OneBeforeFirst = First->Prev;+ Result.OnePastLast = Last->Next;++ First->Prev = Last->Next = (kbts_glyph *)&Storage->GlyphSentinel;+ First->Prev->Next = First;+ Last->Next->Prev = Last;++ return Result;+}++static void kbts__PopGlyphList(kbts_glyph_storage *Storage, kbts__glyph_list *List)+{+ List->OneBeforeFirst->Next = Storage->GlyphSentinel.Next;+ List->OnePastLast->Prev = Storage->GlyphSentinel.Prev;++ // Storage->GlyphSentinel.Prev->Next = Storage->GlyphSentinel.Next->Prev = &Storage->GlyphSentinel;++ if((kbts_glyph *)&Storage->GlyphSentinel != List->OneBeforeFirst)+ {+ Storage->GlyphSentinel.Next = List->SentinelNext;+ }+ if((kbts_glyph *)&Storage->GlyphSentinel != List->OnePastLast)+ {+ Storage->GlyphSentinel.Prev = List->SentinelPrev;+ }++ Storage->GlyphSentinel.Prev->Next = Storage->GlyphSentinel.Next->Prev = (kbts_glyph *)&Storage->GlyphSentinel;++ *List = KBTS__ZERO_TYPE(kbts__glyph_list);+}++static int kbts__WouldSubstitute(kbts__shape_scratchpad *Scratchpad, kbts_shape_config *Config, kbts_glyph_storage *Storage,+ kbts_lookup_list *LookupList,+ kbts__gsub_frame *Frames, kbts__feature *Feature, kbts__skip_flags SkipFlags,+ kbts_glyph *Glyphs, kbts_un GlyphCount)+{+ int Result = 0;++ KBTS_ASSERT(GlyphCount <= 4);+ kbts_glyph TempSentinel;+ kbts_glyph Scratch[4];++ KBTS__FOR(GlyphIndex, 0, GlyphCount)+ {+ kbts_glyph *ScratchGlyph = &Scratch[GlyphIndex];++ // Glyphs is assumed to be in-order on the stack or something.+ // This is one of the rare places where we manipulate arrays.+ *ScratchGlyph = Glyphs[GlyphIndex];+ ScratchGlyph->Prev = ScratchGlyph - 1;+ ScratchGlyph->Next = ScratchGlyph + 1;+ }+ Scratch[0].Prev = &TempSentinel;+ Scratch[GlyphCount - 1].Next = &TempSentinel;+ TempSentinel.Next = &Scratch[0];+ TempSentinel.Prev = &Scratch[GlyphCount - 1];++ kbts__glyph_list OldList = kbts__PushGlyphList(Storage, &Scratch[0], &Scratch[GlyphCount - 1]);++ kbts__iterate_lookups IterateLookups = kbts__IterateLookups(LookupList, Feature);+ while(kbts__NextLookup(&IterateLookups))+ {+ kbts_glyph *CurrentGlyph = &Scratch[0];+ while(kbts__GlyphIsValid(Storage, CurrentGlyph))+ {+ kbts__gsub_frame *Frame = &Frames[0];+ *Frame = KBTS__ZERO_TYPE(kbts__gsub_frame);+ Frame->LookupIndex = IterateLookups.LookupIndex;+ Frame->SubtableIndex = 0;+ Frame->StartIndex = 0;+ Frame->InputGlyph = CurrentGlyph;+ kbts_un FrameCount = 1;++ kbts__BeginLookupApplication(Scratchpad, CurrentGlyph);++ while(FrameCount)+ {+ kbts__substitution_result_flags SubstitutionResult = kbts__DoSubstitution(Scratchpad, Config, Storage, LookupList, Frames, &FrameCount, 1, SkipFlags, 0);++ if(SubstitutionResult & KBTS__SUBSTITUTION_RESULT_FLAG_MATCHED_SUBSTITUTION)+ {+ Result = 1;+ goto Done;+ }+ }++ CurrentGlyph = kbts__EndLookupApplication(Scratchpad);+ }+ }++Done:;+ kbts__PopGlyphList(Storage, &OldList);++ return Result;+}++static int kbts__NextLookupIndex(kbts__shape_scratchpad *Scratchpad, kbts_shape_config *Config, kbts_un *LookupIndex_, kbts_u32 *SkipFlags_, kbts_u32 *GlyphFilter_, kbts__feature_set *FeatureSet_)+{+ int Result = 0;++ kbts_un FeatureStageIndex = Scratchpad->FeatureStagesRead - 1;+ kbts_u32 SkipFlags = 0;+ kbts_u32 GlyphFilter = 0;+ Scratchpad->UnregisteredFeatureCount = 0;+ kbts_un ResultLookupIndex = 0;+ kbts__baked_feature_stage *FeatureStage = &Config->FeatureStages[FeatureStageIndex];++ *FeatureSet_ = KBTS__ZERO_TYPE(kbts__feature_set);++ while(Scratchpad->FeatureIndexIndex < FeatureStage->FeatureIndexCount)+ {+ KBTS_ASSERT(Scratchpad->FeatureIndexIndex < FeatureStage->FeatureIndexCount);++ kbts_u16 FeatureIndex = FeatureStage->FeatureIndices[Scratchpad->FeatureIndexIndex];+ KBTS_ASSERT(FeatureIndex < FeatureStage->FeatureIndexCount);++ kbts__baked_feature *Feature = &FeatureStage->Features[FeatureIndex];+ kbts_un Offset = Scratchpad->BakedLookupSubtablesRead[FeatureIndex];++ KBTS_ASSERT(Offset < Feature->Count);+ kbts_un LookupIndex = Feature->Indices[Offset];++ if(!Result)+ {+ ResultLookupIndex = LookupIndex;+ Result = 1;+ }++ if(LookupIndex == ResultLookupIndex)+ {+ kbts__AddFeature(FeatureSet_, Feature->FeatureId);+ SkipFlags |= Feature->SkipFlags;+ GlyphFilter |= Feature->GlyphFilter;++ if(!Feature->FeatureId && (Scratchpad->UnregisteredFeatureCount < KBTS_MAX_SIMULTANEOUS_FEATURES))+ {+ Scratchpad->UnregisteredFeatureTags[Scratchpad->UnregisteredFeatureCount++] = Feature->FeatureTag;+ }++ Scratchpad->FeatureIndexIndex += 1;+ Scratchpad->BakedLookupSubtablesRead[FeatureIndex] += 1;+ }+ else+ {+ break;+ }+ }++ *LookupIndex_ = ResultLookupIndex;+ *SkipFlags_ = SkipFlags;+ *GlyphFilter_ = GlyphFilter;++ return Result;+}++static int kbts__ConfigAllowsFeatures(kbts__shape_scratchpad *Scratchpad, kbts_u64 DefaultEnabled, kbts_glyph_config *GlyphConfig, kbts__feature_set *Features)+{+ int Result = DefaultEnabled != 0;++ if(GlyphConfig)+ {+ kbts_u64 UserEnabled = 0; // Whether the user enabled _any_ feature corresponding to this lookup.+ kbts_u64 UserDisabled = 1; // Whether the user disabled _all_ features corresponding to this lookup.++ kbts_u64 Mask = 1; // Ignore unregistered features in the broad pass.+ KBTS__FOR(WordIndex, 0, KBTS__ARRAY_LENGTH(GlyphConfig->EnabledFeatures.Flags))+ {+ kbts_u64 LookupFeatureFlags = Features->Flags[WordIndex] & ~Mask;+ Mask = 0;++ UserEnabled |= GlyphConfig->EnabledFeatures.Flags[WordIndex] & LookupFeatureFlags;+ UserDisabled &= (GlyphConfig->DisabledFeatures.Flags[WordIndex] & LookupFeatureFlags) == LookupFeatureFlags;+ }++ if(Features->Flags[0] & (GlyphConfig->EnabledFeatures.Flags[0] | GlyphConfig->DisabledFeatures.Flags[0]) & KBTS__FEATURE_FLAG0(UNREGISTERED))+ {+ // Slow path for unregistered features.+ for(kbts__feature_override_header *Header = GlyphConfig->FeatureOverrideSentinel.Next;+ Header != &GlyphConfig->FeatureOverrideSentinel;+ Header = Header->Next)+ {+ kbts__feature_override *Override = (kbts__feature_override *)Header;+ kbts__feature_id Id = kbts__FeatureTagToId(Override->Tag);++ if(Id == KBTS__FEATURE_ID_UNREGISTERED)+ {+ kbts_feature_tag OverrideTag = Override->Tag;++ KBTS__FOR(UnregisteredFeatureIndex, 0, Scratchpad->UnregisteredFeatureCount)+ {+ if(OverrideTag == Scratchpad->UnregisteredFeatureTags[UnregisteredFeatureIndex])+ {+ UserEnabled |= (kbts_u32)Override->Value;+ UserDisabled &= !Override->Value;+ break;+ }+ }+ }+ }+ }++ Result = (!UserDisabled && (DefaultEnabled || UserEnabled));+ }++ return Result;+}++static void kbts__DllistReverseSublist(kbts_glyph *First, kbts_glyph *OnePastLast)+{+ kbts_glyph *OneBeforeFirst = First->Prev;+ kbts_glyph *Last = First;++ for(kbts_glyph *Glyph = First;+ ;+ )+ {+ kbts_glyph *Next = Glyph->Next;++ Glyph->Next = Glyph->Prev;+ Glyph->Prev = Next;++ Last = Glyph;+ Glyph = Next;+ if(Glyph == OnePastLast)+ {+ break;+ }+ }++ if(First != OnePastLast)+ {+ Last->Prev = OneBeforeFirst;+ Last->Prev->Next = Last;+ First->Next = OnePastLast;+ First->Next->Prev = First;+ }+}++static void kbts__ExecuteOp(kbts__shape_scratchpad *Scratchpad, kbts_shape_config *Config, kbts_glyph_storage *Storage)+{+ KBTS_INSTRUMENT_FUNCTION_BEGIN;++ if(Config)+ {+ kbts_font *Font = Config->Font;+ kbts__op_kind OpKind = Scratchpad->OpKind;++ switch(OpKind)+ {+ case KBTS__OP_KIND_PRE_NORMALIZE_DOTTED_CIRCLES:+ {+ KBTS_INSTRUMENT_BLOCK_BEGIN(PRE_NORMALIZE_DOTTED_CIRCLES);++ // Before even trying to normalize anything, there are some _exceptions_ we have to take care of.+ // The USE spec gives us a list of codepoint sequences which necessitate insertion of a dotted circle.+ // These sequences are from IndicShapingInvalidClusters.txt.+ kbts_u64 Codepoints; Codepoints = 0; // 0xABBBBBCCCCCDDDDD+ KBTS__FOR_GLYPH(Storage, Glyph)+ {+ kbts_u32 NewCodepoint; NewCodepoint = Glyph->Codepoint & 0x1FFFFF;+ Codepoints = (Codepoints << 21) | NewCodepoint;++ // This switch is faster than any table lookup I could come up with in my tests.+ #define KBTS_C2(A, B) case (((kbts_u64)(A) << 21) | (kbts_u64)(B)):+ switch(Codepoints & (((kbts_u64)1 << 42) - 1))+ {+ default:+ if((Codepoints & (((kbts_u64)1 << 63) - 1)) == (((kbts_u64)0x930 << 42) | ((kbts_u64)0x94D << 21) | ((kbts_u64)0x907)))+ {+ KBTS_C2(0x905, 0x93A)+ KBTS_C2(0x905, 0x93B)+ KBTS_C2(0x905, 0x93E)+ KBTS_C2(0x905, 0x945)+ KBTS_C2(0x905, 0x946)+ KBTS_C2(0x905, 0x949)+ KBTS_C2(0x905, 0x94A)+ KBTS_C2(0x905, 0x94B)+ KBTS_C2(0x905, 0x94C)+ KBTS_C2(0x905, 0x94F)+ KBTS_C2(0x905, 0x956)+ KBTS_C2(0x905, 0x957)+ KBTS_C2(0x906, 0x93A)+ KBTS_C2(0x906, 0x945)+ KBTS_C2(0x906, 0x946)+ KBTS_C2(0x906, 0x947)+ KBTS_C2(0x906, 0x948)+ KBTS_C2(0x909, 0x941)+ KBTS_C2(0x90F, 0x945)+ KBTS_C2(0x90F, 0x946)+ KBTS_C2(0x90F, 0x947)+ KBTS_C2(0x985, 0x9BE)+ KBTS_C2(0x98B, 0x9C3)+ KBTS_C2(0x98C, 0x9E2)+ KBTS_C2(0xA05, 0xA3E)+ KBTS_C2(0xA05, 0xA48)+ KBTS_C2(0xA05, 0xA4C)+ KBTS_C2(0xA72, 0xA3F)+ KBTS_C2(0xA72, 0xA40)+ KBTS_C2(0xA72, 0xA47)+ KBTS_C2(0xA73, 0xA41)+ KBTS_C2(0xA73, 0xA42)+ KBTS_C2(0xA73, 0xA4B)+ KBTS_C2(0xA85, 0xABE)+ KBTS_C2(0xA85, 0xAC5)+ KBTS_C2(0xA85, 0xAC7)+ KBTS_C2(0xA85, 0xAC8)+ KBTS_C2(0xA85, 0xAC9)+ KBTS_C2(0xA85, 0xACB)+ KBTS_C2(0xA85, 0xACC)+ KBTS_C2(0xAC5, 0xABE)+ KBTS_C2(0xB05, 0xB3E)+ KBTS_C2(0xB0F, 0xB57)+ KBTS_C2(0xB13, 0xB57)+ KBTS_C2(0xB85, 0xBC2)+ KBTS_C2(0xC12, 0xC4C)+ KBTS_C2(0xC12, 0xC55)+ KBTS_C2(0xC3F, 0xC55)+ KBTS_C2(0xC46, 0xC55)+ KBTS_C2(0xC4A, 0xC55)+ KBTS_C2(0xC89, 0xCBE)+ KBTS_C2(0xC8B, 0xCBE)+ KBTS_C2(0xC92, 0xCCC)+ KBTS_C2(0xD07, 0xD57)+ KBTS_C2(0xD09, 0xD57)+ KBTS_C2(0xD0E, 0xD46)+ KBTS_C2(0xD12, 0xD3E)+ KBTS_C2(0xD12, 0xD57)+ KBTS_C2(0xD85, 0xDCF)+ KBTS_C2(0xD85, 0xDD0)+ KBTS_C2(0xD85, 0xDD1)+ KBTS_C2(0xD8B, 0xDDF)+ KBTS_C2(0xD8D, 0xDD8)+ KBTS_C2(0xD8F, 0xDDF)+ KBTS_C2(0xD91, 0xDCA)+ KBTS_C2(0xD91, 0xDD9)+ KBTS_C2(0xD91, 0xDDA)+ KBTS_C2(0xD91, 0xDDC)+ KBTS_C2(0xD91, 0xDDD)+ KBTS_C2(0xD91, 0xDDE)+ KBTS_C2(0xD94, 0xDDF)+ KBTS_C2(0x11005, 0x11038)+ KBTS_C2(0x1100B, 0x1103E)+ KBTS_C2(0x1100F, 0x11042)+ KBTS_C2(0x11200, 0x1122C)+ KBTS_C2(0x11200, 0x11231)+ KBTS_C2(0x11200, 0x11233)+ KBTS_C2(0x11206, 0x1122C)+ KBTS_C2(0x1122C, 0x11230)+ KBTS_C2(0x1122C, 0x11231)+ KBTS_C2(0x11240, 0x1122E)+ KBTS_C2(0x112B0, 0x112E0)+ KBTS_C2(0x112B0, 0x112E5)+ KBTS_C2(0x112B0, 0x112E6)+ KBTS_C2(0x112B0, 0x112E7)+ KBTS_C2(0x112B0, 0x112E8)+ KBTS_C2(0x11481, 0x114B0)+ KBTS_C2(0x1148B, 0x114BA)+ KBTS_C2(0x1148D, 0x114BA)+ KBTS_C2(0x114AA, 0x114B5)+ KBTS_C2(0x114AA, 0x114B6)+ KBTS_C2(0x11600, 0x11639)+ KBTS_C2(0x11600, 0x1163A)+ KBTS_C2(0x11601, 0x11639)+ KBTS_C2(0x11601, 0x1163A)+ KBTS_C2(0x11680, 0x116AD)+ KBTS_C2(0x11680, 0x116B4)+ KBTS_C2(0x11680, 0x116B5)+ KBTS_C2(0x11686, 0x116B2)+ {+ kbts_glyph *NewGlyph = kbts__InsertGlyphBefore(Storage, Glyph, &Config->DottedCircle);+ if(!NewGlyph)+ {+ goto OutOfMemory;+ }+ } break;+ }+ }+ #undef KBTS_C2+ }++ KBTS_INSTRUMENT_BLOCK_END(PRE_NORMALIZE_DOTTED_CIRCLES);+ } break;++ case KBTS__OP_KIND_NORMALIZE:+ {+ KBTS_INSTRUMENT_BLOCK_BEGIN(NORMALIZE);+ // @Incomplete: We need to honor this.+ // HB_OT_SHAPE_NORMALIZATION_MODE_NONE,+ // HB_OT_SHAPE_NORMALIZATION_MODE_AUTO,+ // HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, /* Always fully decomposes and then recompose back */+ //+ // hangul: HB_OT_SHAPE_NORMALIZATION_MODE_NONE,+ // arabic: HB_OT_SHAPE_NORMALIZATION_MODE_AUTO,+ // default: HB_OT_SHAPE_NORMALIZATION_MODE_AUTO,+ // hebrew: HB_OT_SHAPE_NORMALIZATION_MODE_AUTO,+ // thai: HB_OT_SHAPE_NORMALIZATION_MODE_AUTO,+ // indic: HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT,+ // khmer: HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT,+ // myanmar: HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT,+ // use: HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT,++ KBTS_INSTRUMENT_BLOCK_BEGIN(Decompose);+ { // Full NFD decomposition+ kbts__arena_lifetime Lifetime = kbts__BeginLifetime(Scratchpad->Arena);+ kbts_glyph *DecompositionGlyphs = kbts__PushArray(Scratchpad->Arena, kbts_glyph, KBTS__MAXIMUM_DECOMPOSITION_CODEPOINTS);+ kbts_un CodepointsToDecomposeCount = 0;++ KBTS__FOR_GLYPH(Storage, Glyph)+ {+ if(kbts__GetDecompositionSize(Glyph->Decomposition))+ {+ kbts_glyph *PrevAnchor = Glyph->Prev;++ DecompositionGlyphs[0] = *Glyph;+ CodepointsToDecomposeCount = 1;++ kbts__FreeGlyph(Scratchpad, Storage, Glyph);++ while(CodepointsToDecomposeCount)+ {+ kbts_glyph GlyphToDecompose = DecompositionGlyphs[--CodepointsToDecomposeCount];+ kbts_u64 Decomposition = 0;+ kbts_u32 DecompositionSize = 0;+ int AnyUnsupported = 0;+ kbts_glyph Decomposed[2];++ if(!(GlyphToDecompose.Flags & KBTS_GLYPH_FLAG_DO_NOT_DECOMPOSE))+ {+ Decomposition = GlyphToDecompose.Decomposition;+ DecompositionSize = kbts__GetDecompositionSize(Decomposition);++ // Only decompose when the font supports the decomposed form.+ KBTS__FOR(DecompositionIndex, 0, DecompositionSize)+ {+ kbts_glyph DecompositionGlyph = kbts_CodepointToGlyph(Font, (int)kbts__GetDecompositionCodepoint(Decomposition, DecompositionIndex), 0, 0);+ DecompositionGlyph.Config = GlyphToDecompose.Config;+ DecompositionGlyph.UserIdOrCodepointIndex = GlyphToDecompose.UserIdOrCodepointIndex;++ AnyUnsupported |= !DecompositionGlyph.Id;+ Decomposed[DecompositionIndex] = DecompositionGlyph;+ }+ }++ if(AnyUnsupported | !DecompositionSize)+ {+ kbts_glyph *NewGlyph = kbts__InsertGlyphAfter(Storage, PrevAnchor, &GlyphToDecompose);+ if(!NewGlyph)+ {+ goto OutOfMemory;+ }++ PrevAnchor = NewGlyph;+ }+ else+ {+ KBTS_ASSERT((CodepointsToDecomposeCount + DecompositionSize) <= KBTS__MAXIMUM_DECOMPOSITION_CODEPOINTS);++ if(Decomposition & KBTS_UNICODE_DECOMPOSITION_DO_NOT_RECURSE0)+ {+ Decomposed[0].Flags |= KBTS_GLYPH_FLAG_DO_NOT_DECOMPOSE;+ }+ if(Decomposition & KBTS_UNICODE_DECOMPOSITION_DO_NOT_RECURSE1)+ {+ Decomposed[1].Flags |= KBTS_GLYPH_FLAG_DO_NOT_DECOMPOSE;+ }++ KBTS__FOR(DecompositionIndex, 0, DecompositionSize)+ {+ // We reverse the glyphs here because we use a stack.+ DecompositionGlyphs[CodepointsToDecomposeCount++] = Decomposed[DecompositionSize - 1 - DecompositionIndex];+ }+ }+ }++ Glyph = PrevAnchor;+ }+ }++ kbts__EndLifetime(&Lifetime);+ }+ KBTS_INSTRUMENT_BLOCK_END(Decompose);++ KBTS_INSTRUMENT_BLOCK_BEGIN(Recompose);+ { // Selective recomposition.+ // The OpenType shaping documents say that Hebrew Alphabetic Presentation Form compositions aren't canonical,+ // but looking at UnicodeData.txt, it seems like they totally are, so they are handled here.+ kbts__arena_lifetime Lifetime = kbts__BeginLifetime(Scratchpad->Arena);+ kbts_glyph *LastBase = 0;+ kbts_un LastBaseParentCount = 0;+ kbts_un PreSlashDecimalDigitCount = 0;+ kbts_glyph *PreSlashGlyph = 0;+ kbts_glyph *DigitGlyph = 0;+ kbts_un DecimalDigitCount = 0;+ int InFraction = 0;+ kbts_u32 LastBaseParentsLoaded = 0;+ kbts_glyph_parent LastBaseParents[KBTS_MAXIMUM_RECOMPOSITION_PARENTS];+ kbts_glyph *Parents = kbts__PushArray(Scratchpad->Arena, kbts_glyph, KBTS_MAXIMUM_RECOMPOSITION_PARENTS);++ kbts_u32 BeforeFractionSlashGlyphFlags = KBTS_GLYPH_FLAG_NUMR | KBTS_GLYPH_FLAG_FRAC;+ kbts_u32 AfterFractionSlashGlyphFlags = KBTS_GLYPH_FLAG_DNOM | KBTS_GLYPH_FLAG_FRAC;+ if(kbts__ShaperRtl(Config->Shaper))+ {+ // RTL needs to invert NUMR and DNOM.+ kbts_u32 Swap = BeforeFractionSlashGlyphFlags;+ BeforeFractionSlashGlyphFlags = AfterFractionSlashGlyphFlags;+ AfterFractionSlashGlyphFlags = Swap;+ }++ // We also collate user features here.+ kbts__feature_set UserFeatures = KBTS__ZERO;+ kbts__feature_set *DefaultFeatures = &Config->Features;++ int ShouldFlip = (Scratchpad->RunDirection == KBTS_DIRECTION_RTL);++ KBTS__FOR_GLYPH(Storage, Glyph)+ {+ Glyph->Uid = (kbts_u16)++Scratchpad->NextGlyphUid;++ if(Glyph->Config)+ {+ kbts_glyph_config *GlyphConfig = Glyph->Config;+ KBTS__FOR(WordIndex, 0, KBTS__ARRAY_LENGTH(UserFeatures.Flags))+ {+ UserFeatures.Flags[WordIndex] |= GlyphConfig->EnabledFeatures.Flags[WordIndex] & ~DefaultFeatures->Flags[WordIndex];+ }+ }++ // In RTL, mirror all glyphs when their mirror is covered.+ if(ShouldFlip &&+ (Glyph->UnicodeFlags & KBTS_UNICODE_FLAG_MIRRORED))+ {+ kbts_u32 MatchingBracketCodepoint = kbts__GetUnicodeMirrorCodepoint(Glyph->Codepoint);+ kbts_glyph MatchingBracket = kbts_CodepointToGlyph(Font, (int)MatchingBracketCodepoint, 0, 0);+ if(MatchingBracket.Id)+ {+ kbts__SetGlyphPreserveLinksAndUserId(Glyph, &MatchingBracket);+ }+ }++ kbts_u32 SingleRecompositionCodepoints[KBTS_MAXIMUM_RECOMPOSITION_PARENTS];+ kbts_un SingleRecompositionCodepointCount = 0;+ kbts_un DoubleRecompositionCount = LastBaseParentCount;++ if(!Glyph->CombiningClass)+ {+ LastBase = Glyph;+ // From the Microsoft docs:+ // USE decomposes split vowel characters belonging to UISC = Vowel_Dependent according to character+ // decomposition mappings defined in UnicodeData.txt+ // Cluster validation, is done based on the decomposed state of a split vowel.+ //+ // (Note: our Matra corresponds to Vowel_Dependent + Pure_Killer.)+ if((Config->Shaper != KBTS_SHAPER_USE) || (Glyph->SyllabicClass != KBTS_INDIC_SYLLABIC_CLASS_MATRA))+ {+ kbts_s32 *LastBaseParentDeltas = kbts__GetParentInfoDeltas(Glyph->ParentInfo);+ kbts_un ParentCount = kbts__GetParentInfoCount(Glyph->ParentInfo);++ kbts_un DoubleDecompositionCount = 0;+ KBTS__FOR(ParentIndex, 0, ParentCount)+ {+ kbts_glyph_parent Parent = KBTS__ZERO;+ Parent.Codepoint = Glyph->Codepoint + (kbts_u32)LastBaseParentDeltas[ParentIndex];+ Parent.Decomposition = kbts__GetUnicodeDecomposition(Parent.Codepoint);++ kbts_un DecompositionSize = kbts__GetDecompositionSize(Parent.Decomposition);+ if(DecompositionSize == 1)+ {+ SingleRecompositionCodepoints[SingleRecompositionCodepointCount++] = Parent.Codepoint;+ }+ else+ {+ LastBaseParents[DoubleDecompositionCount++] = Parent;+ }+ }++ LastBaseParentCount = DoubleDecompositionCount;+ LastBaseParentsLoaded = 0;+ }+ else+ {+ LastBaseParentCount = 0;+ }++ DoubleRecompositionCount = 0;+ }++ int Recomposed = 0;++ if(!Recomposed)+ {+ KBTS_INSTRUMENT_BLOCK_BEGIN(ParentNSquaredStupidity);+ KBTS__FOR(ParentIndex, 0, DoubleRecompositionCount)+ {+ kbts_glyph_parent *Parent = &LastBaseParents[ParentIndex];+ kbts_u32 Codepoint1 = kbts__GetDecompositionCodepoint(Parent->Decomposition, 1);++ if(Glyph->Codepoint == Codepoint1)+ {+ kbts_glyph *ParentGlyph = &Parents[ParentIndex];+ if(!(LastBaseParentsLoaded & (1 << ParentIndex)))+ {+ *ParentGlyph = kbts_CodepointToGlyph(Font, (int)Parent->Codepoint, 0, 0);+ ParentGlyph->Uid = LastBase->Uid;+ ParentGlyph->UserIdOrCodepointIndex = LastBase->UserIdOrCodepointIndex;+ ParentGlyph->Config = LastBase->Config;+ }++ if(ParentGlyph->Id)+ {+ // Both match. Reclaim space.+ kbts_glyph *Next = Glyph->Next;+ KBTS__DLLIST_REMOVE(Glyph);+ Glyph = Next;++ Recomposed = 1;+ kbts__SetGlyphPreserveLinksAndUserId(LastBase, ParentGlyph);++ break;+ }+ else+ {+ // This glyph is never good. Forget it.+ LastBaseParents[ParentIndex] = LastBaseParents[LastBaseParentCount - 1];+ Parents[ParentIndex] = Parents[LastBaseParentCount - 1];+ LastBaseParentsLoaded &= ~(1 << ParentIndex);+ LastBaseParentsLoaded |= (LastBaseParentsLoaded & (1 << (LastBaseParentCount - 1))) >> (LastBaseParentCount - 1 - ParentIndex);++ LastBaseParentCount -= 1;+ DoubleRecompositionCount -= 1;+ ParentIndex -= 1;+ }+ }+ }+ KBTS_INSTRUMENT_BLOCK_END(ParentNSquaredStupidity);+ }++ if(!Recomposed)+ {+ KBTS__FOR(SingleRecompositionIndex, 0, SingleRecompositionCodepointCount)+ {+ kbts_glyph ParentGlyph = kbts_CodepointToGlyph(Font, (int)SingleRecompositionCodepoints[SingleRecompositionIndex], 0, 0);+ if(ParentGlyph.Id)+ {+ ParentGlyph.Config = Glyph->Config;++ kbts__SetGlyphPreserveLinksAndUserId(Glyph, &ParentGlyph);+ Recomposed = 1;+ break;+ }+ }+ }++ // It is safe to look for fractions here, because decimal digits/the fraction slash are not marks or+ // jamos, so they should not get reordered after this pass.+ if(Glyph->UnicodeFlags & KBTS_UNICODE_FLAG_DECIMAL_DIGIT)+ {+ if(InFraction)+ {+ // We are in the post-slash part of the fraction.+ Glyph->Flags |= AfterFractionSlashGlyphFlags;+ // Only flag the pre-slash part of the fraction if there is a post-slash part.+ KBTS__FOR(DecimalDigitIndex, 0, PreSlashDecimalDigitCount)+ {+ PreSlashGlyph->Flags |= BeforeFractionSlashGlyphFlags;+ PreSlashGlyph = PreSlashGlyph->Next;+ }+ PreSlashDecimalDigitCount = 0;+ }+ if(!DecimalDigitCount)+ {+ DigitGlyph = Glyph;+ }+ DecimalDigitCount += 1;+ }+ else if((Glyph->Codepoint == 0x2044) && (!InFraction || DecimalDigitCount))+ {+ // Fraction slash.+ Glyph->Flags |= KBTS_GLYPH_FLAG_FRAC;+ PreSlashDecimalDigitCount = DecimalDigitCount;+ PreSlashGlyph = DigitGlyph;+ InFraction = DecimalDigitCount != 0;+ DecimalDigitCount = 0;+ }+ else+ {+ InFraction = 0;+ }++ if(Recomposed)+ {+ // @Robustness: This doesn't work when LastBase != Glyph->Prev, does it?+ Glyph = Glyph->Prev; // Handle recursive recomposition.+ }+ }++ // Ignore added features that are already part of the shaper.+ kbts__feature_set *ShaperFeatures = &Config->Features;+ KBTS__FOR(WordIndex, 0, KBTS__ARRAY_LENGTH(UserFeatures.Flags))+ {+ UserFeatures.Flags[WordIndex] &= ~ShaperFeatures->Flags[WordIndex];+ }++ Scratchpad->UserFeatures = UserFeatures;+ kbts__EndLifetime(&Lifetime);+ }+ KBTS_INSTRUMENT_BLOCK_END(Recompose);++ KBTS_INSTRUMENT_BLOCK_BEGIN(MarkReordering);+ { // Unicode mark reordering.+ for(kbts_glyph *Glyph = Storage->GlyphSentinel.Next;+ kbts__GlyphIsValid(Storage, Glyph);+ )+ {+ kbts_u8 CombiningClass = Glyph->CombiningClass;++ if(CombiningClass)+ {+ Glyph->MarkOrdering = CombiningClass;++ kbts_glyph *SequenceGlyph = Glyph->Next;+ for(;+ kbts__GlyphIsValid(Storage, SequenceGlyph);+ SequenceGlyph = SequenceGlyph->Next)+ {+ kbts_u8 SequenceGlyphCombiningClass = SequenceGlyph->CombiningClass;+ if(SequenceGlyphCombiningClass)+ {+ SequenceGlyph->MarkOrdering = SequenceGlyphCombiningClass;+ }+ else+ {+ break;+ }+ }++ kbts_glyph *AfterSequence = SequenceGlyph;+ if(kbts__GlyphIsValid(Storage, AfterSequence))+ {+ AfterSequence = AfterSequence->Next;+ }++ KBTS__DLLIST_SORT(Glyph, SequenceGlyph, MarkOrdering);++ #ifdef KBTS_SANITY_CHECK+ {+ kbts_glyph *Glyph0 = OneBeforeSequence->Next;+ kbts_glyph *Glyph1 = Glyph0->Next;+ KBTS__FOR(SequenceIndex, 1, MarkSequenceLength)+ {+ KBTS_ASSERT(Glyph0->MarkOrdering <= Glyph1->MarkOrdering);++ Glyph0 = Glyph0->Next;+ Glyph1 = Glyph1->Next;+ }+ }+ #endif++ Glyph = AfterSequence;+ }+ else+ {+ Glyph = Glyph->Next;+ }+ }+ }+ KBTS_INSTRUMENT_BLOCK_END(MarkReordering);++ if(Config->Script == KBTS_SCRIPT_ARABIC)+ {+ for(kbts_glyph *Glyph = Storage->GlyphSentinel.Next;+ kbts__GlyphIsValid(Storage, Glyph);+ )+ {+ kbts_glyph *Next = Glyph->Next;++ // Find a mark sequence.+ kbts_u8 CombiningClass = Glyph->CombiningClass;++ if(CombiningClass)+ {+ // Arabic: Reorder sequences of mark glyphs.+ //+ // From the Unicode standard:+ // - Move any shadda characters (ccc=33) to the beginning of S.+ // - If a sequence of ccc=230 characters begins with any MCM characters, move the sequence of such MCM+ // characters+ // to the beginning of S (before any characters with ccc=33).+ // - If a sequence of ccc=220 characters begins with any MCM characters, move the sequence of such MCM+ // characters+ // to the beginning of S (before any MCM with ccc=230 or ccc=33).+ //+ // Final ordering: 220 230 shadda other++ kbts__mcm_sequence_state Mcm220SequenceState = 0;+ kbts__mcm_sequence_state Mcm230SequenceState = 0;++ # define KBTS_REMAPPED_CCC_33 27++ kbts_glyph *SequenceGlyph = Glyph;+ for(;+ kbts__GlyphIsValid(Storage, SequenceGlyph);+ SequenceGlyph = SequenceGlyph->Next)+ {+ kbts_u16 SequenceGlyphCombiningClass = SequenceGlyph->CombiningClass;+ kbts_u16 SequenceGlyphFlags = SequenceGlyph->UnicodeFlags;++ kbts_u8 MarkOrdering = 3;++ if(SequenceGlyphCombiningClass == KBTS_REMAPPED_CCC_33)+ {+ MarkOrdering = 2;+ }+ else if(SequenceGlyphCombiningClass == 220)+ {+ if(SequenceGlyphFlags & KBTS_UNICODE_FLAG_MODIFIER_COMBINING_MARK)+ {+ if(Mcm220SequenceState != KBTS__MCM_SEQUENCE_STATE_OUT)+ {+ Mcm220SequenceState = KBTS__MCM_SEQUENCE_STATE_IN;+ }+ }+ else+ {+ Mcm220SequenceState = KBTS__MCM_SEQUENCE_STATE_OUT;+ }++ if(Mcm220SequenceState == KBTS__MCM_SEQUENCE_STATE_IN)+ {+ MarkOrdering = 0;+ }++ Mcm230SequenceState = KBTS__MCM_SEQUENCE_STATE_NONE;+ }+ else if(SequenceGlyphCombiningClass == 230)+ {+ if(SequenceGlyphFlags & KBTS_UNICODE_FLAG_MODIFIER_COMBINING_MARK)+ {+ if(Mcm230SequenceState != KBTS__MCM_SEQUENCE_STATE_OUT)+ {+ Mcm230SequenceState = KBTS__MCM_SEQUENCE_STATE_IN;+ }+ }+ else+ {+ Mcm230SequenceState = KBTS__MCM_SEQUENCE_STATE_OUT;+ }++ if(Mcm230SequenceState == KBTS__MCM_SEQUENCE_STATE_IN)+ {+ MarkOrdering = 1;+ }+ }+ else if(SequenceGlyphCombiningClass)+ {+ Mcm220SequenceState = KBTS__MCM_SEQUENCE_STATE_NONE;+ Mcm230SequenceState = KBTS__MCM_SEQUENCE_STATE_NONE;+ }+ else+ {+ break;+ }++ SequenceGlyph->MarkOrdering = MarkOrdering;+ }++ KBTS__DLLIST_SORT(Glyph, SequenceGlyph, MarkOrdering);++ #ifdef KBTS_SANITY_CHECK+ {+ kbts_glyph *Glyph0 = OneBeforeGlyph->Next;+ for(kbts_glyph *Glyph1 = Glyph0->Next;+ Glyph1 != SequenceGlyph;+ Glyph1 = Glyph1->Next)+ {+ KBTS_ASSERT(Glyph0->MarkOrdering <= Glyph1->MarkOrdering);+ Glyph0 = Glyph1;+ }+ }+ #endif++ Next = SequenceGlyph;+ }++ Glyph = Next;+ }+ }+ else if((Config->Script == KBTS_SCRIPT_THAI) || (Config->Script == KBTS_SCRIPT_LAO))+ {+ // Decompose sara/sala ams.+ kbts_glyph *AboveBaseGlyph; AboveBaseGlyph = 0;++ KBTS__FOR_GLYPH(Storage, Glyph)+ {+ kbts_u32 Codepoint = Glyph->Codepoint;++ switch(Codepoint)+ {+ // Sara am/sala am.+ // We match both because storing the sara am codepoint that corresponds to the current script+ // doesn't seem that worthwhile, given that this is already a pretty big switch case.+ // If we choose to use a unicode flag or indic syllabic category to notate above-base marks,+ // then this loops gets a lot tighter and it would probably become the right call to pre-determine+ // the sara am codepoint.+ case 0xE33: case 0xEB3: // Sara am+ {+ kbts_glyph *NewGlyph = kbts__InsertGlyphBefore(Storage, AboveBaseGlyph, &Config->Nikhahit);+ if(!NewGlyph)+ {+ goto OutOfMemory;+ }++ kbts__SetGlyphPreserveLinksAndUserId(Glyph, &Config->SaraAa);+ } break;++ case 0xE31: case 0xE34: case 0xE35: case 0xE36: case 0xE37: case 0xE3B:+ case 0xE47: case 0xE48: case 0xE49: case 0xE4A: case 0xE4B: case 0xE4C: case 0xE4D: case 0xE4E:+ case 0xEB1: case 0xEB4: case 0xEB5: case 0xEB6: case 0xEB7: case 0xEBB:+ case 0xEC7: case 0xEC8: case 0xEC9: case 0xECA: case 0xECB: case 0xECC: case 0xECD: case 0xECE:+ if(!AboveBaseGlyph)+ {+ AboveBaseGlyph = Glyph;+ }+ break;++ default:+ AboveBaseGlyph = 0;+ break;+ }+ }+ }++ KBTS_INSTRUMENT_BLOCK_END(NORMALIZE);+ } break;++ case KBTS__OP_KIND_NORMALIZE_HANGUL:+ {+ KBTS_INSTRUMENT_BLOCK_BEGIN(NORMALIZE_HANGUL);++ for(kbts_glyph *Glyph = Storage->GlyphSentinel.Next;+ kbts__GlyphIsValid(Storage, Glyph);+ )+ {+ kbts_glyph *Next = Glyph->Next;++ kbts_un L = 0;+ kbts_un V = 0;+ kbts_un T = 0;+ kbts_un LvtGlyphCount = 0;+ kbts_glyph LvtGlyphs[4];++ kbts__hangul_syllable_info LInfo = kbts__HangulSyllableInfo(Glyph->Codepoint);+ if(LInfo.Type >= KBTS__HANGUL_SYLLABLE_TYPE_LV)+ {+ kbts_un SIndex = (Glyph->Codepoint - 0xAC00);++ L = 0x1100 + SIndex / 588;+ V = 0x1161 + (SIndex % 588) / 28;++ kbts_un TIndex = SIndex % 28;+ if(TIndex)+ {+ T = 0x11A7 + TIndex;+ }+ }+ else if(LInfo.Type == KBTS__HANGUL_SYLLABLE_TYPE_L)+ {+ L = Glyph->Codepoint;+ }++ if(L)+ {+ kbts__hangul_syllable_info VInfo = KBTS__ZERO;++ if(!V && kbts__GlyphIsValid(Storage, Next))+ {+ kbts_u32 VCodepoint = Next->Codepoint;++ VInfo = kbts__HangulSyllableInfo(VCodepoint);++ if(VInfo.Type == KBTS__HANGUL_SYLLABLE_TYPE_V)+ {+ V = VCodepoint;++ Next = Next->Next;+ }+ }++ if(V)+ {+ kbts__hangul_syllable_info TInfo = KBTS__ZERO;++ if(!T && kbts__GlyphIsValid(Storage, Next))+ {+ kbts_u32 TCodepoint = Next->Codepoint;++ TInfo = kbts__HangulSyllableInfo(TCodepoint);++ if(TInfo.Type == KBTS__HANGUL_SYLLABLE_TYPE_T)+ {+ T = TCodepoint;++ Next = Next->Next;+ }+ }++ // Check for any tone marks that we need to swap to the front of the syllable.+ // The OpenType shaping documents say that we need to do this after applying GSUB features, but+ // harfbuzz does it before, so it's probably fine to do it here?+ // It's also basically free to do here, which is nice.+ if(kbts__GlyphIsValid(Storage, Next))+ {+ kbts_u32 ToneMarkCodepoint = Next->Codepoint;++ if((ToneMarkCodepoint >= 0x302E) && (ToneMarkCodepoint <= 0x302F))+ {+ LvtGlyphs[LvtGlyphCount++] = kbts_CodepointToGlyph(Font, (int)ToneMarkCodepoint, 0, 0);++ Next = Next->Next;+ }+ }++ if(LInfo.Composable & VInfo.Composable & TInfo.Composable)+ {+ // Try LVT.+ kbts_un LvtCodepoint = 0xAC00 + (L - 0x1100) * 588 + (V - 0x1161) * 28 + (T - 0x11A7);++ kbts_glyph LvtGlyph = kbts_CodepointToGlyph(Font, (int)LvtCodepoint, 0, 0);+ if(LvtGlyph.Id)+ {+ LvtGlyphs[LvtGlyphCount++] = LvtGlyph;+ }+ }++ if(!LvtGlyphCount)+ {+ kbts_glyph LvGlyph = KBTS__ZERO;+ if(LInfo.Composable & VInfo.Composable)+ {+ // Try LV.+ kbts_un LvCodepoint = 0xAC00 + (L - 0x1100) * 588 + (V - 0x1161) * 28;++ LvGlyph = kbts_CodepointToGlyph(Font, (int)LvCodepoint, 0, 0);+ }++ if(LvGlyph.Id)+ {+ LvtGlyphs[LvtGlyphCount++] = LvGlyph;+ }+ else+ {+ // Do L-V.+ kbts_glyph LGlyph = kbts_CodepointToGlyph(Font, (int)L, 0, 0);+ LGlyph.Flags |= KBTS_GLYPH_FLAG_LJMO;++ kbts_glyph VGlyph = kbts_CodepointToGlyph(Font, (int)V, 0, 0);+ VGlyph.Flags |= KBTS_GLYPH_FLAG_VJMO;++ LvtGlyphs[LvtGlyphCount++] = LGlyph;+ LvtGlyphs[LvtGlyphCount++] = VGlyph;+ }++ if(T)+ {+ kbts_glyph TGlyph = kbts_CodepointToGlyph(Font, (int)T, 0, 0);+ TGlyph.Flags |= KBTS_GLYPH_FLAG_TJMO;++ LvtGlyphs[LvtGlyphCount++] = TGlyph;+ }+ }+ }+ }++ if(!LvtGlyphCount)+ {+ kbts_glyph NewGlyph = kbts_CodepointToGlyph(Font, (int)Glyph->Codepoint, 0, 0);++ LvtGlyphs[LvtGlyphCount++] = NewGlyph;+ }++ { // Insert the LVT glyphs.+ kbts_glyph *LastConsumed = Next->Prev;++ // Remove the sub-list from the main list.+ Glyph->Prev->Next = LastConsumed->Next;+ LastConsumed->Next->Prev = Glyph->Prev;++ // Send it to the free list.+ Glyph->Prev = (kbts_glyph *)&Storage->FreeGlyphSentinel;+ LastConsumed->Next = Storage->FreeGlyphSentinel.Next;+ Glyph->Prev->Next = Glyph;+ LastConsumed->Next->Prev = LastConsumed;++ for(kbts_un LvtGlyphIndex = 0;+ LvtGlyphIndex < LvtGlyphCount;+ ++LvtGlyphIndex)+ {+ kbts_glyph *LvtGlyph = &LvtGlyphs[LvtGlyphIndex];+ kbts_glyph *NewGlyph = kbts__InsertGlyphBefore(Storage, Next, LvtGlyph);++ if(!NewGlyph)+ {+ goto OutOfMemory;+ }+ }+ }++ Glyph = Next;+ }++ KBTS_INSTRUMENT_BLOCK_END(NORMALIZE_HANGUL);+ }+ break;++ case KBTS__OP_KIND_GSUB_FEATURES:+ {+ KBTS_INSTRUMENT_BLOCK_BEGIN(GSUB_FEATURES);++ if(kbts__BeginFeatures(Scratchpad, Config, KBTS_SHAPING_TABLE_GSUB))+ {+ kbts__gsub_gpos *FontGsub = kbts__BlobTableDataType(Font->Blob, KBTS_BLOB_TABLE_ID_GSUB, kbts__gsub_gpos);+ kbts_lookup_list *LookupList = kbts__GetLookupList(FontGsub);++ kbts__arena_lifetime Lifetime = kbts__BeginLifetime(Scratchpad->Arena);+ kbts__gsub_frame *Frames = kbts__PushArray(Scratchpad->Arena, kbts__gsub_frame, KBTS_LOOKUP_STACK_SIZE);++ kbts_u32 FilterMask = Config->Shaper == KBTS_SHAPER_USE ? KBTS__USE_GLYPH_FEATURE_MASK : KBTS__GLYPH_FEATURE_MASK;+ kbts_un GlyphCount = Font->Blob->GlyphCount;+ kbts_u32 *GlyphLookupMatrix = 0;+ if(Font->Blob->GlyphLookupMatrixOffsetFromStartOfFile)+ {+ GlyphLookupMatrix = KBTS__POINTER_OFFSET(kbts_u32, Font->Blob, Font->Blob->GlyphLookupMatrixOffsetFromStartOfFile);+ }++ kbts_u32 GlyphFilter;+ kbts__skip_flags SkipFlags;+ kbts_un LookupIndex;+ while(kbts__NextLookupIndex(Scratchpad, Config, &LookupIndex, &SkipFlags, &GlyphFilter, &Scratchpad->LookupFeatures))+ {+ kbts_u64 DefaultEnabled = 0;+ kbts_u64 UserEnabled = 0;+ KBTS__FOR(WordIndex, 0, KBTS__ARRAY_LENGTH(Scratchpad->LookupFeatures.Flags))+ {+ DefaultEnabled |= Config->Features.Flags[WordIndex] & Scratchpad->LookupFeatures.Flags[WordIndex];+ UserEnabled |= Scratchpad->UserFeatures.Flags[WordIndex] & Scratchpad->LookupFeatures.Flags[WordIndex];+ }++ if(DefaultEnabled | UserEnabled)+ {+ kbts__lookup *Lookup = kbts__GetLookup(LookupList, LookupIndex);+ int LookupTypeIs8 = (Lookup->Type == 8);+ kbts_glyph *GlyphSentinel = &Storage->GlyphSentinel;++ // From the Microsoft docs:+ // If a Lookup table has multiple subtables, the subtables are processed in order, testing the glyph sequence+ // at the current glyph position for a match with the input sequence patterns specified by each subtable in+ // turn.+ //+ // This means the subtable loop is _inside_ of the loop over our glyphs.++ // Reverse chaining substitutions are tricky.+ // See the comment at :ReverseChaining.+ for(kbts_glyph *Glyph = LookupTypeIs8 ? GlyphSentinel->Prev : GlyphSentinel->Next;+ kbts__GlyphIsValid(Storage, Glyph);+ )+ {+ kbts_u16 GlyphId = Glyph->Id;+ kbts_u32 GlyphFlags = Glyph->Flags;++ kbts__BeginLookupApplication(Scratchpad, Glyph);+ kbts_u32 EffectiveGlyphFilter = GlyphFilter & FilterMask;++ kbts_u32 InMatrix = 1;+ if(GlyphLookupMatrix &&+ (GlyphId < GlyphCount))+ {+ kbts__matrix_index MatrixIndex = kbts__GlyphLookupMatrixIndex(LookupIndex, GlyphId, GlyphCount);+ InMatrix = GlyphLookupMatrix[MatrixIndex.WordIndex] & (1 << MatrixIndex.BitIndex);+ }++ if(InMatrix &&+ kbts__ConfigAllowsFeatures(Scratchpad, DefaultEnabled, Glyph->Config, &Scratchpad->LookupFeatures) &&+ ((GlyphFlags & EffectiveGlyphFilter) == EffectiveGlyphFilter))+ {+ kbts__gsub_frame FirstFrame = KBTS__ZERO;+ FirstFrame.LookupIndex = (kbts_u16)LookupIndex;+ FirstFrame.InputGlyph = Glyph;++ Frames[0] = FirstFrame;+ kbts_un FrameCount = 1;++ while(FrameCount)+ {+ // These flags are used by USE.+ kbts_u32 GeneratedGlyphFlags = GlyphFilter & (KBTS_GLYPH_FLAG_RPHF | KBTS_GLYPH_FLAG_PREF);+ kbts__DoSubstitution(Scratchpad, Config, Storage, LookupList, Frames, &FrameCount, 0, SkipFlags, GeneratedGlyphFlags);+ }+ }++ kbts_glyph *OnePastLast = kbts__EndLookupApplication(Scratchpad);+ Glyph = LookupTypeIs8 ? Glyph->Prev : OnePastLast;+ }+ }+ }++ kbts__EndLifetime(&Lifetime);+ }++ KBTS_INSTRUMENT_BLOCK_END(GSUB_FEATURES);+ }+ break;++ case KBTS__OP_KIND_FLAG_JOINING_LETTERS:+ {+ KBTS_INSTRUMENT_BLOCK_BEGIN(FLAG_JOINING_LETTERS);+ kbts_u64 JoiningTypesMatchLookup =+ (((1ull << KBTS_UNICODE_JOINING_TYPE_RIGHT) | (1ull << KBTS_UNICODE_JOINING_TYPE_DUAL) | (1ull << KBTS_UNICODE_JOINING_TYPE_FORCE)) << (8 * KBTS_UNICODE_JOINING_TYPE_LEFT)) |+ (((1ull << KBTS_UNICODE_JOINING_TYPE_RIGHT) | (1ull << KBTS_UNICODE_JOINING_TYPE_DUAL) | (1ull << KBTS_UNICODE_JOINING_TYPE_FORCE)) << (8 * KBTS_UNICODE_JOINING_TYPE_DUAL)) |+ (((1ull << KBTS_UNICODE_JOINING_TYPE_RIGHT) | (1ull << KBTS_UNICODE_JOINING_TYPE_DUAL) | (1ull << KBTS_UNICODE_JOINING_TYPE_FORCE)) << (8 * KBTS_UNICODE_JOINING_TYPE_FORCE));++ kbts_u64 JoiningFeatureTransition = ((kbts_u64)KBTS_JOINING_FEATURE_INIT << (8 * KBTS_JOINING_FEATURE_ISOL)) | ((kbts_u64)KBTS_JOINING_FEATURE_MEDI << (8 * KBTS_JOINING_FEATURE_FINA)) |+ ((kbts_u64)KBTS_JOINING_FEATURE_MEDI << (8 * KBTS_JOINING_FEATURE_MEDI)) | ((kbts_u64)KBTS_JOINING_FEATURE_MED2 << (8 * KBTS_JOINING_FEATURE_MED2));++ // Tag letters for joining features.+ kbts_glyph PreviousGlyph_ = KBTS__ZERO;+ kbts_glyph *PreviousGlyph = &PreviousGlyph_;+ KBTS__FOR_GLYPH(Storage, Glyph)+ {+ if(Glyph->JoiningType != KBTS_UNICODE_JOINING_TYPE_TRANSPARENT)+ {+ Glyph->JoiningFeature = (kbts_joining_feature)(!PreviousGlyph->JoiningType ? KBTS_JOINING_FEATURE_INIT : KBTS_JOINING_FEATURE_FINA);++ if(JoiningTypesMatchLookup & (1ull << (Glyph->JoiningType + 8 * PreviousGlyph->JoiningType)))+ {+ PreviousGlyph->JoiningFeature = (JoiningFeatureTransition >> (8 * PreviousGlyph->JoiningFeature)) & 0xFF;+ PreviousGlyph->Flags = (PreviousGlyph->Flags & ~KBTS__JOINING_FEATURE_MASK) | KBTS__JOINING_FEATURE_TO_GLYPH_FLAG(PreviousGlyph->JoiningFeature);++ Glyph->JoiningFeature = KBTS_JOINING_FEATURE_FINA;+ }+ else+ {+ Glyph->JoiningFeature = KBTS_JOINING_FEATURE_ISOL;+ }++ if(Glyph->JoiningFeature)+ {+ // Be careful that this properly maps kbts_joining_feature to KBTS_GLYPH_FLAG!+ Glyph->Flags = (Glyph->Flags & ~KBTS__JOINING_FEATURE_MASK) | KBTS__JOINING_FEATURE_TO_GLYPH_FLAG(Glyph->JoiningFeature);+ }++ PreviousGlyph = Glyph;+ }+ }++ KBTS_INSTRUMENT_BLOCK_END(FLAG_JOINING_LETTERS);+ }+ break;++ case KBTS__OP_KIND_GPOS_METRICS:+ {+ KBTS_INSTRUMENT_BLOCK_BEGIN(GPOS_METRICS);+ // hmtx/vmtx pass.+ int ClearMarkAdvances = (Config->Shaper == KBTS_SHAPER_MYANMAR) || (Config->Shaper == KBTS_SHAPER_USE);++ kbts_u32 Orientation = KBTS_ORIENTATION_HORIZONTAL; // @Hardcoded+ kbts_blob_table_id HeaTableId = KBTS_BLOB_TABLE_ID_HHEA;+ kbts_blob_table_id MtxTableId = KBTS_BLOB_TABLE_ID_HMTX;+ if(Orientation == KBTS_ORIENTATION_VERTICAL)+ {+ HeaTableId = KBTS_BLOB_TABLE_ID_VHEA;+ MtxTableId = KBTS_BLOB_TABLE_ID_VMTX;+ }++ kbts__hea *Hea = kbts__BlobTableDataType(Font->Blob, HeaTableId, kbts__hea);+ kbts_u16 *Mtx = kbts__BlobTableDataType(Font->Blob, MtxTableId, kbts_u16);++ kbts__long_mtx *LongMetrics = 0;+ // :LeftSideBearing+ // kbts_s16 *ShortMetrics = 0;+ if(Hea && Mtx)+ {+ LongMetrics = (kbts__long_mtx *)Mtx;+ // :LeftSideBearing+ // ShortMetrics = (kbts_s16 *)(LongMetrics + Hea->MetricCount);+ }++ kbts__long_mtx DefaultMetric = {1024, 0};+ kbts__head *Head = kbts__BlobTableDataType(Font->Blob, KBTS_BLOB_TABLE_ID_HEAD, kbts__head);+ if(Head)+ {+ DefaultMetric.Advance = Head->UnitsPerEm;+ if(Orientation == KBTS_ORIENTATION_HORIZONTAL)+ {+ DefaultMetric.Advance /= 2;+ }+ }++ KBTS__FOR_GLYPH(Storage, Glyph)+ {+ kbts__SetCursiveFlags(Glyph, 0);++ kbts__long_mtx Metric = DefaultMetric;+ if(LongMetrics)+ {+ kbts_u32 Id = Glyph->Id;++ // At the end of shaping, default ignorable glyphs that are not generated by GSUB are replaced with zero-width+ // whitespace glyphs (or a zero-width empty glyph if no whitespace glyph is present).+ // (By the way, we do this because Harfbuzz does it, and Harfbuzz does it probably because Uniscribe does it.)+ // We handle this in two steps:+ // - The first is here. We want cursive attachments, and mark-to-base attachments, and other relative placements+ // to take the zero width into account, and zeroing the width right at the beginning of GPOS is the most+ // straighforward way to accomplish this.+ // (@Incomplete: It is likely that we also need to take the default ignorable case into account when accumulating+ // cursive offsets.)+ // - In POST_GPOS_FIXUP, we perform the glyph ID substitution. We have to wait until all GPOS features have been+ // executed to do this because they might possibly match the original ID.+ if(!(Glyph->Flags & KBTS_GLYPH_FLAG_GENERATED_BY_GSUB) && (Glyph->UnicodeFlags & KBTS_UNICODE_FLAG_DEFAULT_IGNORABLE))+ {+ Metric.Advance = 0;+ // :LeftSideBearing+ // Metric.PreviousSideBearing = 0;+ }+ else if(Id < Hea->MetricCount)+ {+ Metric = LongMetrics[Id];+ }+ else+ {+ Metric.Advance = LongMetrics[Hea->MetricCount - 1].Advance;+ // :LeftSideBearing+ // Metric.PreviousSideBearing = ShortMetrics[Id - Hea->MetricCount];+ }+ }++ if(!ClearMarkAdvances | (Glyph->Classes.Class != KBTS__GLYPH_CLASS_MARK))+ {+ if(Orientation == KBTS_ORIENTATION_HORIZONTAL)+ {+ // :LeftSideBearing+ // Why does harfbuzz not take bearings into account in these tests?+ // P.X += Metric.PreviousSideBearing;+ Glyph->AdvanceX = Metric.Advance;+ }+ else+ {+ // :LeftSideBearing+ // Why does harfbuzz not take bearings into account in these tests?+ // P.Y += Metric.PreviousSideBearing;+ Glyph->AdvanceY = Metric.Advance;+ }+ }+ }+ KBTS_INSTRUMENT_BLOCK_END(GPOS_METRICS);+ }+ break;++ case KBTS__OP_KIND_GPOS_FEATURES:+ {+ KBTS_INSTRUMENT_BLOCK_BEGIN(GPOS_FEATURES);++ if(kbts__BeginFeatures(Scratchpad, Config, KBTS_SHAPING_TABLE_GPOS))+ {+ kbts__gsub_gpos *Gpos = kbts__BlobTableDataType(Font->Blob, KBTS_BLOB_TABLE_ID_GPOS, kbts__gsub_gpos);+ kbts__gdef *Gdef = kbts__BlobTableDataType(Font->Blob, KBTS_BLOB_TABLE_ID_GDEF, kbts__gdef);+ kbts_un GlyphCount = Font->Blob->GlyphCount;+ kbts_un GposLookupIndexOffset = Font->Blob->GposLookupIndexOffset;+ kbts_u32 *GlyphLookupMatrix = 0;+ if(Font->Blob->GlyphLookupMatrixOffsetFromStartOfFile)+ {+ GlyphLookupMatrix = KBTS__POINTER_OFFSET(kbts_u32, Font->Blob, Font->Blob->GlyphLookupMatrixOffsetFromStartOfFile);+ }++ kbts_lookup_list *LookupList = kbts__GetLookupList(Gpos);+ kbts_un LookupIndex;+ kbts__skip_flags SkipFlags;+ kbts_u32 GlyphFilter;+ while(kbts__NextLookupIndex(Scratchpad, Config, &LookupIndex, &SkipFlags, &GlyphFilter, &Scratchpad->LookupFeatures))+ {+ KBTS_INSTRUMENT_BLOCK_BEGIN(GposUserLookups);++ // @Duplication with GSUB.+ kbts_u64 DefaultEnabled = 0;+ kbts_u64 UserEnabled = 0;+ KBTS__FOR(WordIndex, 0, KBTS__ARRAY_LENGTH(Scratchpad->LookupFeatures.Flags))+ {+ DefaultEnabled |= Scratchpad->LookupFeatures.Flags[WordIndex] & Config->Features.Flags[WordIndex];+ UserEnabled |= Scratchpad->LookupFeatures.Flags[WordIndex] & Scratchpad->UserFeatures.Flags[WordIndex];+ }++ if(DefaultEnabled | UserEnabled)+ {+ kbts__lookup *PackedLookup = kbts__GetLookup(LookupList, LookupIndex);+ kbts__unpacked_lookup Lookup = kbts__UnpackLookup(Gdef, PackedLookup);++ kbts_glyph *Glyph = Storage->GlyphSentinel.Next;+ while(kbts__GlyphIsValid(Storage, Glyph))+ {+ kbts_u16 GlyphId = Glyph->Id;+ kbts__BeginLookupApplication(Scratchpad, Glyph);++ kbts_u32 InMatrix = 1;+ if(GlyphLookupMatrix &&+ (GlyphId < GlyphCount))+ {+ kbts__matrix_index MatrixIndex = kbts__GlyphLookupMatrixIndex(GposLookupIndexOffset + LookupIndex, GlyphId, GlyphCount);+ InMatrix = GlyphLookupMatrix[MatrixIndex.WordIndex] & (1 << MatrixIndex.BitIndex);+ }++ if(InMatrix &&+ kbts__ConfigAllowsFeatures(Scratchpad, DefaultEnabled, Glyph->Config, &Scratchpad->LookupFeatures))+ {+ KBTS__FOR(SubtableIndex, 0, Lookup.SubtableCount)+ {+ kbts_u16 *Subtable = KBTS__POINTER_OFFSET(kbts_u16, PackedLookup, Lookup.SubtableOffsets[SubtableIndex]);++ if(kbts__DoSingleAdjustment(Scratchpad, Config, Storage, LookupList,+ LookupIndex, SubtableIndex, &Lookup, Subtable,+ Glyph, 0, SkipFlags))+ {+ break;+ }+ }+ }++ Glyph = kbts__EndLookupApplication(Scratchpad);+ }+ }+ }+ }++ KBTS_INSTRUMENT_BLOCK_END(GPOS_FEATURES);+ }+ break;++ case KBTS__OP_KIND_POST_GPOS_FIXUP:+ {+ KBTS_INSTRUMENT_BLOCK_BEGIN(POST_GPOS_FIXUP);+ kbts_glyph WhitespaceGlyph = Config->Whitespace;+ int ClearMarkAdvances = kbts__ShaperClearsMarkAdvancesInPostGposFixup(Config->Shaper);++ if(Scratchpad->RunDirection == KBTS_DIRECTION_RTL)+ {+ // Flip direction.+ // This might seem like a totally superfluous thing to do, because we have to do a bunch+ // of work to reverse glyph order while still preserving their relative positions.+ // However, for mainly LTR documents, the anchor position will naturally be left-aligned,+ // while, in RTL documents, it will naturally right-align.+ // As such, going through the glyph sequence and reversing it is needed _anyway_ at some point,+ // and we might as well do it here, because this is where we can take resolve attachments+ // for relatively cheap, since they are always back-looking. (The next paragraph explains this+ // in more detail.)++ // The unintuitive part about this pass is the glyph advances.+ // Normally, when iterating over a sequence of glyphs, we see base glyphs before marks. Obviously.+ // However, when flipping the sequence, we see the marks before seeing the bases, which means we+ // won't have accumulated the base glyph's advance yet! So we have to go through the sequence here+ // and compensate for missing advances by precomputing them and baking them into the marks.+ // Another way to reach the same result would be to keep marks on the same side as their bases when+ // flipping, but that is not what Harfbuzz does, and, the day we decide we want to diverge from Harfbuzz,+ // we will very likely be better off not flipping the sequence at all and deleting all of this garbage code.+ kbts_s32 MarkAttachAdvanceX = 0;+ kbts_s32 MarkAttachAdvanceY = 0;+ KBTS__FOR_GLYPH(Storage, Glyph)+ {+ kbts_glyph *Attach = Glyph->AttachGlyph;+ if(Attach)+ {+ kbts_s32 AttachAdvanceX = MarkAttachAdvanceX;+ kbts_s32 AttachAdvanceY = MarkAttachAdvanceY;+ if(Attach->Classes.Class != KBTS__GLYPH_CLASS_MARK)+ {+ AttachAdvanceX = Attach->AdvanceX;+ AttachAdvanceY = Attach->AdvanceY;+ }+ Glyph->OffsetX += AttachAdvanceX;+ Glyph->OffsetY += AttachAdvanceY;+ MarkAttachAdvanceX = AttachAdvanceX;+ MarkAttachAdvanceY = AttachAdvanceY;+ }+ }++ // Swap.+ // @Speed: We could just choose the correct links when traversing instead.+ kbts__DllistReverseSublist((kbts_glyph *)&Storage->GlyphSentinel, (kbts_glyph *)&Storage->GlyphSentinel);+ }++ // Make default ignorables that weren't explicitly created by the font invisible.+ //+ // It is tempting to put this loop inside of an if(WhitespaceGlyph.Id), just like we do+ // for dotted circle insertion. However, Harfbuzz does not do this!+ // When the font does not contain a dotted circle, nothing is inserted, but when the font+ // does not contain a whitespace glyph, _we still insert an empty glyph_.+ for(kbts_glyph *Glyph = Storage->GlyphSentinel.Next;+ kbts__GlyphIsValid(Storage, Glyph);+ )+ {+ kbts_glyph *Next = Glyph->Next;+ int Keep = 0;++ // It might be tempting to keep glyphs that were used in GPOS, but Harfbuzz doesn't care.+ if(!(Glyph->Flags & KBTS_GLYPH_FLAG_GENERATED_BY_GSUB) && (Glyph->UnicodeFlags & KBTS_UNICODE_FLAG_DEFAULT_IGNORABLE))+ {+ // This glyph is default ignorable and should be ignored.+ if(WhitespaceGlyph.Id)+ {+ Keep = 1;+ kbts__SetGlyphPreserveLinksAndUserId(Glyph, &WhitespaceGlyph);+ }+ }+ else+ {+ if(ClearMarkAdvances && (Glyph->Classes.Class == KBTS__GLYPH_CLASS_MARK))+ {+ Glyph->AdvanceX = Glyph->AdvanceY = 0;+ }+ Keep = 1;+ }++ if(!Keep)+ {+ kbts__FreeGlyph(Scratchpad, Storage, Glyph);+ }++ Glyph = Next;+ }++ KBTS_INSTRUMENT_BLOCK_END(POST_GPOS_FIXUP);+ }+ break;++ case KBTS__OP_KIND_STCH_POSTPASS:+ {+ #if 0+ KBTS__FOR_GLYPH(ShapeState, Glyph)+ {+ if(Glyph->Flags & (KBTS_GLYPH_FLAG_STCH_ENDPOINT | KBTS_GLYPH_FLAG_STCH_EXTENSION))+ {+ kbts_glyph *Extension = 0;++ kbts_s32 EndpointWidth = 0;+ kbts_s32 ExtensionWidth = 0;++ while(kbts__GlyphIsValid(ShapeState, Glyph))+ {+ kbts_glyph *AtGlyph = &Glyphs[At];++ if(AtGlyph->Flags & KBTS_GLYPH_FLAG_STCH_ENDPOINT)+ {+ EndpointWidth += AtGlyph->AdvanceX;++ At += 1;+ }+ else if(AtGlyph->Flags & KBTS_GLYPH_FLAG_STCH_EXTENSION)+ {+ ExtensionIndex = At;+ ExtensionWidth += AtGlyph->AdvanceX;+ SawExtension = 1;++ At += 1;+ }+ else+ {+ break;+ }+ }++ kbts_sn WordWidth = 0;++ while(At < GlyphArray->Count)+ {+ kbts_glyph *AtGlyph = &Glyphs[At];++ int Ok = 0;++ if(!(AtGlyph->Flags & (KBTS_GLYPH_FLAG_STCH_ENDPOINT | KBTS_GLYPH_FLAG_STCH_EXTENSION)) && (AtGlyph->UnicodeFlags & KBTS_UNICODE_FLAG_PART_OF_WORD))+ {+ Ok = 1;+ }++ if(Ok)+ {+ WordWidth += AtGlyph->AdvanceX;++ At += 1;+ }+ else+ {+ break;+ }+ }++ if(WordWidth > EndpointWidth)+ {+ kbts_sn ExtensionCount = (WordWidth - EndpointWidth) / ExtensionWidth;+ if((ExtensionWidth * ExtensionCount) < (WordWidth - EndpointWidth))+ {+ ExtensionCount += 1;+ }++ (void)ExtensionCount;+ (void)ExtensionIndex;+ (void)SawExtension;+ /* @Incomplete+ kbts_glyph_adjustment *ExtensionAdjustment = &Positions[ExtensionIndex];+ ExtensionAdjustment->LastRepeatIndex = ExtensionCount - 1;+ ExtensionAdjustment->RepeatOffsetX = (WordWidth - EndpointWidth - ExtensionWidth) / ExtensionCount;+ */+ }++ GlyphIndex = At;+ }+ }+ #endif+ }+ break;+ }++ if(0)+ {+ OutOfMemory:;+ Scratchpad->Error = KBTS_SHAPE_ERROR_OUT_OF_MEMORY;+ }+ }++ KBTS_INSTRUMENT_FUNCTION_END;+}++static kbts_glyph kbts__Substitute1(kbts__shape_scratchpad *Scratchpad, kbts_shape_config *Config, kbts_glyph_storage *Storage,+ kbts_lookup_list *LookupList, kbts__feature *Feature, kbts__skip_flags SkipFlags, kbts_glyph *Glyph)+{+ kbts_glyph Result = *Glyph;+ kbts_glyph TempSentinel;+ TempSentinel.Prev = TempSentinel.Next = &Result;+ Result.Prev = Result.Next = &TempSentinel;+ kbts__glyph_list List = kbts__PushGlyphList(Storage, &Result, &Result);++ kbts__iterate_lookups IterateLookups = kbts__IterateLookups(LookupList, Feature);+ while(kbts__NextLookup(&IterateLookups))+ {+ kbts__gsub_frame Frames[8];+ {+ kbts__gsub_frame *Frame = &Frames[0];+ *Frame = KBTS__ZERO_TYPE(kbts__gsub_frame);+ Frame->LookupIndex = IterateLookups.LookupIndex;+ Frame->SubtableIndex = 0;+ Frame->StartIndex = 0;+ Frame->InputGlyph = &Result;+ }+ kbts_un FrameCount = 1;++ while(FrameCount)+ {+ kbts__substitution_result_flags SubstitutionResult = kbts__DoSubstitution(Scratchpad, Config, Storage,+ LookupList, Frames, &FrameCount, 0, SkipFlags, 0);+ if(SubstitutionResult & KBTS__SUBSTITUTION_RESULT_FLAG_TRIED_TO_INSERT_WHILE_CHECK_ONLY)+ {+ goto Done;+ }+ }+ }++Done:;+ kbts__PopGlyphList(Storage, &List);+ return Result;+}++typedef struct kbts__attach_state+{+ kbts__syllabic_position CurrentPosition;+ kbts__syllabic_position LastPositionThatWasNotPreBaseMatra;+ kbts_indic_syllabic_class LastClass;+ kbts_glyph *Start;+ kbts_glyph *OnePastLast;+ kbts_glyph *At;+} kbts__attach_state;++static kbts_glyph *kbts__BeginCluster(kbts__shape_scratchpad *Scratchpad, kbts_shape_config *Config, kbts_glyph_storage *Storage,+ kbts_glyph *Glyph)+{+ kbts_font *Font = Config->Font;+ kbts_glyph *Result = Glyph->Next;+ kbts__arena_lifetime Lifetime = kbts__BeginLifetime(Scratchpad->Arena);++ Scratchpad->RealCluster = 0;++ switch(Config->Shaper)+ {+ case KBTS_SHAPER_INDIC:+ {+ kbts_lookup_list *LookupList = kbts__GetLookupList(kbts__BlobTableDataType(Font->Blob, KBTS_BLOB_TABLE_ID_GSUB, kbts__gsub_gpos));++ int NonCluster = 0;+ while(kbts__GlyphIsValid(Storage, Glyph) &&+ ((Glyph->SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_OTHER) ||+ (Glyph->SyllabicClass >= KBTS_INDIC_SYLLABIC_CLASS_COUNT)))+ {+ NonCluster = 1;+ Glyph = Glyph->Next;+ }++ Result = Glyph;++ if(!NonCluster)+ {+ kbts_un ScanGlyphIndex = 0;+ kbts_un State = 0;+ kbts_un Broken = 1;+ kbts_un BrokenState = 0;+ kbts_glyph *FirstGlyphs[3];++ while(kbts__GlyphIsValid(Storage, Glyph) &&+ (State < KBTS_INDIC_SYLLABIC_STATE_COUNT))+ {+ kbts_un Class = Glyph->SyllabicClass;++ if(KBTS__IN_SET(Class, KBTS__SET32((KBTS_INDIC_SYLLABIC_CLASS_RA)+ (KBTS_INDIC_SYLLABIC_CLASS_CONSONANT)+ (KBTS_INDIC_SYLLABIC_CLASS_VOWEL)+ (KBTS_INDIC_SYLLABIC_CLASS_DOTTED_CIRCLE)+ (KBTS_INDIC_SYLLABIC_CLASS_PLACEHOLDER)+ (KBTS_INDIC_SYLLABIC_CLASS_SYMBOL))))+ {+ Broken = 0;+ }+ BrokenState = (BrokenState << 1) | Broken;++ if(ScanGlyphIndex < KBTS__ARRAY_LENGTH(FirstGlyphs))+ {+ FirstGlyphs[ScanGlyphIndex] = Glyph;+ }++ State = kbts_IndicSyllabicTransition[Class][State];+ State -= 1; // @Incomplete @Cleanup: Decrement every state by 1 in the transition table.+ Glyph = Glyph->Next;+ ScanGlyphIndex += 1;+ }++ if(State > KBTS_INDIC_SYLLABIC_STATE_COUNT)+ {+ ScanGlyphIndex -= State - KBTS_INDIC_SYLLABIC_STATE_COUNT;+ BrokenState >>= State - KBTS_INDIC_SYLLABIC_STATE_COUNT;++ while(State > KBTS_INDIC_SYLLABIC_STATE_COUNT)+ {+ Glyph = Glyph->Prev;+ State -= 1;+ }++ if(!ScanGlyphIndex)+ {+ // If we backtrack all the way to the beginning, still eat a character.+ ScanGlyphIndex = 1;+ }+ }++ // NOTE: Symbols, vedics, modifiers, matras have their syllabic positions tagged at build time.+ // It is tempting to use Unicode's positional information for consonants, too, but OpenType+ // _strongly_ recommends that shapers use the font's tables instead, ie. doing tentative lookups+ // with specific features.++ kbts__gsub_frame *Frames = kbts__PushArray(Scratchpad->Arena, kbts__gsub_frame, KBTS_LOOKUP_STACK_SIZE);+ kbts_glyph *OnePastLastSyllableGlyph = Glyph;+ kbts_glyph *FirstGlyph = FirstGlyphs[0];+ kbts_glyph *OneBeforeSyllableGlyph = FirstGlyph->Prev;++ if((Config->Script == KBTS_SCRIPT_KANNADA) && (ScanGlyphIndex >= 3) &&+ (FirstGlyphs[0]->SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_RA) &&+ (FirstGlyphs[1]->SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_HALANT) &&+ (FirstGlyphs[2]->SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_ZWJ))+ {+ // In older versions of Unicode (~4.x, pre-2004), Ra-Virama-Zwj was recommended in Kannada+ // to communicate the intent of displaying (Ra + (next consonant as below-base form)).+ // This was changed in Unicode 5. Now, the recommended sequence to display (Ra ++ // (next consonant as below-base form)) is Ra-Zwj-Virama.+ // Since Ra-Virama-Zwj is not a useful sequence that happens organically in Kannada,+ // we are free to transform it into Ra-Zwj-Virama here without losing information.+ KBTS__DLLIST_SWAP(FirstGlyphs[1], FirstGlyphs[2]);++ // Also swap this, because this is used below for OnePastReph.+ kbts_glyph *Swap = FirstGlyphs[1];+ FirstGlyphs[1] = FirstGlyphs[2];+ FirstGlyphs[2] = Swap;+ }++ kbts_glyph_flags RephFlags = KBTS_GLYPH_FLAG_RPHF;+ kbts_glyph *OnePastReph = FirstGlyphs[0];+ kbts_un OnePastRephIndex = 0;+ { // Reph tagging.+ // This first pass only figures out where the reph ends.+ // We delay updating glyph properties until we know whether the reph is the base or not.+ kbts_glyph *Second = FirstGlyphs[1];+ kbts_glyph *Third = FirstGlyphs[2];+ kbts__feature *Rphf = Config->Rphf;++ switch(Config->IndicScriptProperties.RephEncoding)+ {+ case KBTS__REPH_ENCODING_LOGICAL_REPHA:+ if(FirstGlyph->SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_REPHA)+ {+ RephFlags = 0;+ OnePastRephIndex = 1;+ }+ break;++ case KBTS__REPH_ENCODING_IMPLICIT:+ if((ScanGlyphIndex >= 2) &&+ (Second->SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_HALANT))+ {+ kbts_glyph Scratch[2];+ Scratch[0] = *FirstGlyphs[0];+ Scratch[1] = *FirstGlyphs[1];++ if(kbts__WouldSubstitute(Scratchpad, Config, Storage, LookupList, Frames, Rphf, 0, Scratch, 2))+ {+ OnePastRephIndex = 2;+ }+ }+ break;++ case KBTS__REPH_ENCODING_EXPLICIT:+ if((ScanGlyphIndex >= 3) &&+ (Second->SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_HALANT) &&+ (Third->SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_ZWJ))+ {+ kbts_glyph Scratch[3];+ Scratch[0] = *FirstGlyphs[0];+ Scratch[1] = *FirstGlyphs[1];+ Scratch[2] = *FirstGlyphs[2];++ if(kbts__WouldSubstitute(Scratchpad, Config, Storage, LookupList, Frames, Rphf, 0, Scratch, 3))+ {+ OnePastRephIndex = 3;+ }+ }+ break;+ }++ // Extend the reph with suffixed joiners.+ if(OnePastRephIndex)+ {+ OnePastReph = FirstGlyphs[OnePastRephIndex - 1]->Next;+ while(kbts__GlyphIsValid(Storage, OnePastReph) &&+ KBTS__IN_SET(OnePastReph->SyllabicClass, KBTS__SET32((KBTS_INDIC_SYLLABIC_CLASS_ZWJ)+ (KBTS_INDIC_SYLLABIC_CLASS_ZWNJ))))+ {+ OnePastReph = OnePastReph->Next;+ }+ }+ }++ kbts__feature *Pref = Config->Pref;+ kbts_glyph *BaseGlyph = OnePastLastSyllableGlyph;+ kbts_glyph *LastConsonant = 0;+ kbts__syllabic_position LastConsonantPosition = KBTS__SYLLABIC_POSITION_SYLLABLE_BASE;+ if(Config->DottedCircle.Id && (BrokenState & 1))+ {+ BaseGlyph = kbts__InsertGlyphBefore(Storage, OnePastReph, &Config->DottedCircle);+ if(!BaseGlyph)+ {+ goto OutOfMemory;+ }++ BaseGlyph->UserIdOrCodepointIndex = OnePastReph->UserIdOrCodepointIndex;+ }+ else+ {+ // Going backwards, tag blwf and pstf consonants until we get to the base.+ kbts_glyph Scratch[3];+ Scratch[0] = Config->Virama;+ Scratch[2] = Config->Virama;++ kbts__feature *Locl = Config->Locl;+ kbts__feature *Vatu = Config->Vatu;++ // pstf forms come last, then blwf.+ kbts__feature *SectionFeature = Config->Pstf;+ kbts__syllabic_position SectionPosition = KBTS__SYLLABIC_POSITION_POSTBASE_CONSONANT;+ // If we see no consonant/matra, then surely we want to attach to the base.+ kbts__syllabic_position SyllabicPosition = KBTS__SYLLABIC_POSITION_SYLLABLE_BASE;+ kbts_indic_syllabic_class LastClass = KBTS_INDIC_SYLLABIC_CLASS_COUNT;++ for(Glyph = OnePastLastSyllableGlyph->Prev;+ ;+ Glyph = Glyph->Prev)+ {+ kbts_indic_syllabic_class Class = Glyph->SyllabicClass;++ switch(Class)+ {+ case KBTS_INDIC_SYLLABIC_CLASS_CONSONANT:+ case KBTS_INDIC_SYLLABIC_CLASS_RA:+ case KBTS_INDIC_SYLLABIC_CLASS_CONSONANT_WITH_STACKER:+ case KBTS_INDIC_SYLLABIC_CLASS_CONSONANT_MEDIAL:+ // Apply locl first.+ Scratch[1] = kbts__Substitute1(Scratchpad, Config, Storage, LookupList, Locl, KBTS__SKIP_FLAG_ZWNJ | KBTS__SKIP_FLAG_ZWJ, Glyph);++ // Microsoft says to "move backwards until a consonant is found that does not have a below-base+ // or post-base form".+ // As with everything else the spec says, it is wrong. There are cases in which the only consonant+ // in a syllable has a below-base or post-base form. In those cases, we still want them to be the+ // syllable base.+ // So, as we sweep backward, set the base index on consonants unconditionally.+ // @Robustness: Do we want to update Base only if we do not match Pref/Vatu?+ BaseGlyph = Glyph;++ if(kbts__WouldSubstitute(Scratchpad, Config, Storage, LookupList, Frames, Pref, 0, Scratch, 2) ||+ kbts__WouldSubstitute(Scratchpad, Config, Storage, LookupList, Frames, Pref, 0, Scratch + 1, 2) ||+ kbts__WouldSubstitute(Scratchpad, Config, Storage, LookupList, Frames, Vatu, 0, Scratch, 2) ||+ kbts__WouldSubstitute(Scratchpad, Config, Storage, LookupList, Frames, Vatu, 0, Scratch + 1, 2))+ {+ SyllabicPosition = KBTS__SYLLABIC_POSITION_POSTBASE_CONSONANT;+ }+ else+ {+ for(;;)+ {+ if(kbts__WouldSubstitute(Scratchpad, Config, Storage, LookupList, Frames, SectionFeature, 0, Scratch, 2) ||+ kbts__WouldSubstitute(Scratchpad, Config, Storage, LookupList, Frames, SectionFeature, 0, Scratch + 1, 2))+ {+ SyllabicPosition = SectionPosition;+ break;+ }+ else if(SectionPosition == KBTS__SYLLABIC_POSITION_POSTBASE_CONSONANT)+ {+ SectionFeature = Config->Blwf;+ SectionPosition = KBTS__SYLLABIC_POSITION_BELOWBASE_CONSONANT;+ // Retry with Blwf.+ }+ else+ {+ goto DoneScanningForBase;+ }+ }+ }++ if(!LastConsonant)+ {+ LastConsonant = Glyph;+ LastConsonantPosition = SyllabicPosition;+ }++ Glyph->SyllabicPosition = SyllabicPosition;+ break;++ case KBTS_INDIC_SYLLABIC_CLASS_VOWEL:+ case KBTS_INDIC_SYLLABIC_CLASS_PLACEHOLDER:+ case KBTS_INDIC_SYLLABIC_CLASS_DOTTED_CIRCLE:+ BaseGlyph = Glyph;+ goto DoneScanningForBase;+ break;++ case KBTS_INDIC_SYLLABIC_CLASS_HALANT:+ if(LastClass == KBTS_INDIC_SYLLABIC_CLASS_ZWJ)+ {+ // Explicit half form.+ // Since half forms are always before the base, we can safely stop here.+ goto DoneScanningForBase;+ }+ case KBTS_INDIC_SYLLABIC_CLASS_NUKTA:+ case KBTS_INDIC_SYLLABIC_CLASS_ZWJ:+ case KBTS_INDIC_SYLLABIC_CLASS_ZWNJ:+ // @Incomplete: Register Shifter+ Glyph->SyllabicPosition = SyllabicPosition;+ break;+ }++ LastClass = Class;+ if(Glyph == OnePastReph)+ {+ break;+ }+ }+ DoneScanningForBase:;+ }++ // Fix reph position now.+ if(OnePastReph != FirstGlyph)+ {+ kbts__syllabic_position RephPosition = KBTS__SYLLABIC_POSITION_RA_TO_BECOME_REPH;+ kbts_glyph_flags Flags = RephFlags;+ kbts_un RephGlyphCount = OnePastRephIndex;+ if(BaseGlyph == OnePastLastSyllableGlyph)+ {+ RephPosition = KBTS__SYLLABIC_POSITION_SYLLABLE_BASE;+ Flags = 0;++ BaseGlyph = OnePastReph = FirstGlyph;+ }++ KBTS__FOR(GlyphIndex, 0, RephGlyphCount)+ {+ kbts_glyph *RephGlyph = FirstGlyphs[GlyphIndex];+ RephGlyph->SyllabicPosition = RephPosition;+ RephGlyph->Flags |= Flags;+ }+ }++ if(BaseGlyph != OnePastLastSyllableGlyph)+ {+ BaseGlyph->SyllabicPosition = KBTS__SYLLABIC_POSITION_SYLLABLE_BASE;++ if(!LastConsonant)+ {+ LastConsonant = BaseGlyph;+ // LastConsonantPosition is already set to SYLLABLE_BASE.+ }+ }++ { // Reorder marks.+ // @Cleanup @Speed: Supposedly, NORMALIZE already does this...+ kbts_glyph *ReorderGlyph = OnePastLastSyllableGlyph->Prev;+ while(ReorderGlyph != OneBeforeSyllableGlyph)+ {+ if(ReorderGlyph->SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_NUKTA)+ {+ kbts_glyph *Prev = ReorderGlyph->Prev;++ while((Prev != OneBeforeSyllableGlyph) &&+ KBTS__IN_SET(Prev->SyllabicClass, KBTS__SET32((KBTS_INDIC_SYLLABIC_CLASS_HALANT)+ (KBTS_INDIC_SYLLABIC_CLASS_VEDIC_SIGN))))+ {+ kbts_glyph *NextPrev = Prev->Prev;++ KBTS__DLLIST_SWAP(Prev, Prev->Next);++ Prev = NextPrev;+ }++ ReorderGlyph = Prev;+ }+ else+ {+ ReorderGlyph = ReorderGlyph->Prev;+ }+ }+ }++ { // @Temporary @Cleanup+ // Left matras should be ordered backwards.+ // We want to bake this ordering into our sort, so we increase our syllabic position bits+ // and sub-order matras with the low nibble. (There should only be 4 matras tops, anyway.)+ kbts_un LeftMatraCount = 0;+ for(Glyph = OneBeforeSyllableGlyph->Next;+ Glyph != OnePastLastSyllableGlyph;+ Glyph = Glyph->Next)+ {+ Glyph->SyllabicPosition <<= 4;++ if(Glyph->SyllabicPosition == (KBTS__SYLLABIC_POSITION_PREBASE_MATRA << 4))+ {+ Glyph->SyllabicPosition += (15 - LeftMatraCount++) & 0xF;+ }+ }+ }++ { // Attach stuff to the right of consonants/matras.+ // Pre-base consonants, the base consonant, and matras all have right attachments,+ // while post-base consonants have left attachments.+ // Since matras always come after all consonants, we try to separate the buffer into three parts:+ // a pre-base+base part (right attachments), a post-base consonant part (left attachments), and+ // a post-consonant part (right attachments again).+ // This part handles right attachments. Left attachments were handled in the base syllable search.+ kbts__attach_state States[2] = {+ {+ KBTS__SYLLABIC_POSITION_RA_TO_BECOME_REPH << 4,+ KBTS__SYLLABIC_POSITION_RA_TO_BECOME_REPH << 4,+ KBTS_INDIC_SYLLABIC_CLASS_COUNT,+ OnePastReph,+ BaseGlyph,+ OnePastReph,+ },+ {+ (kbts_u8)(LastConsonantPosition << 4),+ (kbts_u8)(LastConsonantPosition << 4),+ KBTS_INDIC_SYLLABIC_CLASS_COUNT,+ LastConsonant ? LastConsonant->Next : OnePastLastSyllableGlyph,+ OnePastLastSyllableGlyph,+ LastConsonant ? LastConsonant->Next : OnePastLastSyllableGlyph,+ },+ };+ for(;;)+ {+ int Done = 1;++ KBTS__FOR(StateIndex, 0, KBTS__ARRAY_LENGTH(States))+ {+ kbts__attach_state *Attach = &States[StateIndex];++ if(Attach->At != Attach->OnePastLast)+ {+ Glyph = Attach->At;++ kbts_indic_syllabic_class Class = Glyph->SyllabicClass;+ switch(Class)+ {+ case KBTS_INDIC_SYLLABIC_CLASS_CONSONANT:+ case KBTS_INDIC_SYLLABIC_CLASS_RA:+ case KBTS_INDIC_SYLLABIC_CLASS_CONSONANT_WITH_STACKER:+ case KBTS_INDIC_SYLLABIC_CLASS_CONSONANT_MEDIAL:+ // This only happens in the pre-base state.+ Glyph->SyllabicPosition = (KBTS__SYLLABIC_POSITION_PREBASE_CONSONANT << 4);+ Attach->CurrentPosition = (KBTS__SYLLABIC_POSITION_PREBASE_CONSONANT << 4);+ break;++ case KBTS_INDIC_SYLLABIC_CLASS_MATRA_POST:+ // This specific category (which is composed of a single character) may come after+ // a syllable modifier in a sequence like Consonant-SyllableModifier-MatraPost.+ // In this very particular case (!), the syllable modifier is attached _to the matra_,+ // and not to the consonant.+ if(Attach->LastClass == KBTS_INDIC_SYLLABIC_CLASS_SYLLABLE_MODIFIER)+ {+ Glyph->Prev->SyllabicPosition = Glyph->SyllabicPosition;+ }+ case KBTS_INDIC_SYLLABIC_CLASS_MATRA:+ Attach->CurrentPosition = Glyph->SyllabicPosition;+ if((Attach->CurrentPosition >> 4) != KBTS__SYLLABIC_POSITION_PREBASE_MATRA)+ {+ Attach->LastPositionThatWasNotPreBaseMatra = Attach->CurrentPosition;+ }+ break;++ case KBTS_INDIC_SYLLABIC_CLASS_HALANT:+ if((Attach->CurrentPosition >> 4) == KBTS__SYLLABIC_POSITION_PREBASE_MATRA)+ {+ // Uniscribe does not reorder halants with pre-base matras. Not sure why.+ Glyph->SyllabicPosition = Attach->LastPositionThatWasNotPreBaseMatra;+ break;+ }+ case KBTS_INDIC_SYLLABIC_CLASS_NUKTA:+ case KBTS_INDIC_SYLLABIC_CLASS_ZWJ:+ case KBTS_INDIC_SYLLABIC_CLASS_ZWNJ:+ // @Incomplete: Register Shifter+ Glyph->SyllabicPosition = Attach->CurrentPosition;+ break;+ }++ Attach->LastClass = Class;+ Attach->At = Glyph->Next;+ Done = 0;+ }+ }++ if(Done)+ {+ break;+ }+ }+ }++ { // Do the sort!+ // NOTE: It is important that we sort _now_, because some characters will be reordered across the base from+ // where they started, which can change which features will apply to them.+ KBTS__DLLIST_SORT(OneBeforeSyllableGlyph->Next, OnePastLastSyllableGlyph, SyllabicPosition);++#ifdef KBTS_SANITY_CHECK+ {+ kbts_glyph *Glyph0 = OneBeforeSyllableGlyph->Next;+ if(Glyph0 != OnePastLastSyllableGlyph)+ {+ for(kbts_glyph *Glyph1 = Glyph0->Next;+ kbts__GlyphIsValid(C, Glyph1);+ Glyph1 = Glyph1->Next)+ {+ if(Glyph1 != OnePastLastSyllableGlyph)+ {+ KBTS_ASSERT(Glyph0->SyllabicPosition <= Glyph1->SyllabicPosition);+ }+ else+ {+ break;+ }+ }+ }+ }+ #endif+ }++ // @Temporary @Cleanup+ // Revert our syllabic position shift for now.+ for(Glyph = OneBeforeSyllableGlyph->Next;+ Glyph != OnePastLastSyllableGlyph;+ Glyph = Glyph->Next)+ {+ Glyph->SyllabicPosition >>= 4;+ }++ // This is what Harfbuzz does:++ // - NUKT, AKHN, RKRF, VATU, CJCT are active for all characters, but they count ZWJ/ZWNJ in their sequence+ // lookups.+ // - Note that, by default, Harfbuzz skips ZWJ/ZWNJ in sequence lookups, and selectively disables it for CJCT.+ // - Anyway, since these are active for all characters, we don't need flags for them.++ // (RPHF was already handled before sorting.)++ { // All pre-base glyphs get HALF, which is then selectively disabled in front of ZWNJs.+ kbts_glyph_flags BaseFlags = 0;+ if(!Config->IndicScriptProperties.BlwfPostOnly)+ {+ BaseFlags = KBTS_GLYPH_FLAG_BLWF;+ }++ kbts_indic_syllabic_class LastClass = 0;+ for(Glyph = BaseGlyph->Prev;+ Glyph != OneBeforeSyllableGlyph;+ Glyph = Glyph->Prev)+ {+ kbts_glyph_flags Flags = BaseFlags;++ if(LastClass != KBTS_INDIC_SYLLABIC_CLASS_ZWNJ)+ {+ Flags |= KBTS_GLYPH_FLAG_HALF;+ }++ Glyph->Flags |= Flags;+ LastClass = Glyph->SyllabicClass;+ }+ }++ // All post-base glyphs get BLWF, ABVF, PSTF. Some get PREF.+ kbts_glyph Scratch[2]; Scratch[0] = Scratch[1] = KBTS__ZERO_TYPE(kbts_glyph);+ kbts_glyph *LastGlyph; LastGlyph = 0;+ for(Glyph = BaseGlyph->Next;+ Glyph != OnePastLastSyllableGlyph;+ Glyph = Glyph->Next)+ {+ // It is tempting to apply PREF to every glyph after the base.+ // However, the PREF flag is also used to find the syllable base again in EndCluster,+ // so we have to be precise with it.+ Scratch[1] = *Glyph;+ if(kbts__WouldSubstitute(Scratchpad, Config, Storage, LookupList, Frames, Pref, 0, Scratch, 2))+ {+ LastGlyph->Flags |= KBTS_GLYPH_FLAG_PREF;+ Glyph->Flags |= KBTS_GLYPH_FLAG_PREF;+ }++ Glyph->Flags |= (KBTS_GLYPH_FLAG_BLWF | KBTS_GLYPH_FLAG_ABVF | KBTS_GLYPH_FLAG_PSTF);+ Scratch[0] = Scratch[1];+ LastGlyph = Glyph;+ }++ // The base only inherits stuff after it, up to whatever and not including what was grabbed by+ // post-base consonants.+ if(BaseGlyph != OnePastLastSyllableGlyph)+ {+ BaseGlyph->SyllabicPosition = KBTS__SYLLABIC_POSITION_SYLLABLE_BASE;++ kbts_u64 Classes = (1ull << KBTS_INDIC_SYLLABIC_CLASS_HALANT) |+ (1ull << KBTS_INDIC_SYLLABIC_CLASS_VEDIC_SIGN) |+ (1ull << KBTS_INDIC_SYLLABIC_CLASS_NUKTA) |+ (1ull << KBTS_INDIC_SYLLABIC_CLASS_ZWJ) |+ (1ull << KBTS_INDIC_SYLLABIC_CLASS_ZWNJ);++ kbts_glyph *Next = BaseGlyph->Next;+ while((Next != OnePastLastSyllableGlyph) &&+ (Next->SyllabicPosition < KBTS__SYLLABIC_POSITION_SYLLABLE_BASE) &&+ ((1ull << Next->SyllabicClass) & Classes))+ {+ Next->SyllabicPosition = KBTS__SYLLABIC_POSITION_SYLLABLE_BASE;++ Next = Next->Next;+ }+ }++ Result = OnePastLastSyllableGlyph;+ Scratchpad->RealCluster = 1;+ }+ } break;++ case KBTS_SHAPER_USE:+ {+ int NonCluster = 0;+ while(kbts__GlyphIsValid(Storage, Glyph) &&+ ((Glyph->UseClass == KBTS_USE_SYLLABIC_CLASS_OTHER) ||+ (Glyph->UseClass == KBTS_USE_SYLLABIC_CLASS_CONS_FINAL_MOD_POST)))+ {+ NonCluster = 1;++ Glyph = Glyph->Next;+ }++ if(!NonCluster)+ {+ // Parse a real cluster.+ kbts_u8 State = 0;++ kbts_glyph *StartGlyph = Glyph;+ while(kbts__GlyphIsValid(Storage, Glyph) &&+ (State < KBTS_USE_STATE_s0))+ {+ State = kbts_UseTransition[Glyph->UseClass][State];+ // @Incomplete: Remove this!!!+ State -= 1;+ Glyph = Glyph->Next;+ }++ if(State >= KBTS_USE_STATE_s0)+ {+ Glyph = Glyph->Prev;+ }+ if(kbts__GlyphIsValid(Storage, Glyph) &&+ (Glyph->UseClass == KBTS_USE_SYLLABIC_CLASS_ZWNJ))+ {+ Glyph = Glyph->Next;+ }+ if(Glyph == StartGlyph)+ {+ Glyph = Glyph->Next;+ }++ Scratchpad->RealCluster = 1;+ }++ Result = Glyph;+ } break;++ case KBTS_SHAPER_KHMER:+ {+ int NonCluster = 0;+ while(kbts__GlyphIsValid(Storage, Glyph) &&+ ((Glyph->SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_OTHER) ||+ (Glyph->SyllabicClass >= KBTS_KHMER_SYLLABIC_CLASS_COUNT)))+ {+ Glyph = Glyph->Next;+ NonCluster = 1;+ }++ Result = Glyph;++ if(!NonCluster)+ {+ kbts_u8 State = 0;+ kbts_glyph *FirstGlyph = Glyph;+ kbts_glyph *OneBeforeSyllableGlyph = Glyph->Prev;++ while(kbts__GlyphIsValid(Storage, Glyph) &&+ (State < KBTS_KHMER_SYLLABIC_STATE_COUNT))+ {+ kbts_indic_syllabic_class Class = Glyph->SyllabicClass;++ State = kbts_KhmerSyllabicTransition[Class][State];+ // @Incomplete: Remove this!+ State -= 1;+ Glyph = Glyph->Next;+ }++ if(State >= KBTS_KHMER_SYLLABIC_STATE_COUNT)+ {+ Glyph = Glyph->Prev;+ }+ if(Glyph == FirstGlyph)+ {+ Glyph = Glyph->Next;+ }++ kbts_glyph *OnePastLastSyllableGlyph = Glyph;++ if(Config->DottedCircle.Id &&+ !KBTS__IN_SET64(FirstGlyph->SyllabicClass, KBTS__SET64((KBTS_INDIC_SYLLABIC_CLASS_CONSONANT)+ (KBTS_INDIC_SYLLABIC_CLASS_RA)+ (KBTS_INDIC_SYLLABIC_CLASS_VOWEL)+ (KBTS_INDIC_SYLLABIC_CLASS_DOTTED_CIRCLE)+ (KBTS_INDIC_SYLLABIC_CLASS_PLACEHOLDER))))+ {+ // Broken cluster.+ // Insert a dotted circle.+ kbts_glyph *NewFirstGlyph = kbts__InsertGlyphBefore(Storage, FirstGlyph, &Config->DottedCircle);+ if(!NewFirstGlyph)+ {+ goto OutOfMemory;+ }++ NewFirstGlyph->UserIdOrCodepointIndex = FirstGlyph->UserIdOrCodepointIndex;+ FirstGlyph = NewFirstGlyph;+ }++ // In Khmer, the first glyph is always the base.++ kbts_glyph *PreBaseGlyphs[3];+ int SawHalantRa = 0;+ kbts_un PreBaseGlyphCount = 0;+ kbts_un Classes = 0;++ kbts_u32 AddFlags = KBTS_GLYPH_FLAG_ABVF | KBTS_GLYPH_FLAG_BLWF | KBTS_GLYPH_FLAG_PSTF;++ kbts_glyph *LastGlyph = OnePastLastSyllableGlyph;+ for(Glyph = OnePastLastSyllableGlyph->Prev;+ Glyph != OneBeforeSyllableGlyph;+ Glyph = Glyph->Prev)+ {+ kbts_indic_syllabic_class Class = Glyph->SyllabicClass;++ if(Glyph == FirstGlyph)+ {+ AddFlags = 0;+ }++ Glyph->Flags |= AddFlags;++ Classes = ((Classes << 8) | Class) & 0xFFFF;++ if(Class == KBTS_INDIC_SYLLABIC_CLASS_VOWEL_PRE)+ {+ PreBaseGlyphs[PreBaseGlyphCount++] = Glyph;+ }+ else if(!SawHalantRa && (Classes == (KBTS_INDIC_SYLLABIC_CLASS_HALANT | (KBTS_INDIC_SYLLABIC_CLASS_RA << 8))))+ {+ Glyph->Flags |= KBTS_GLYPH_FLAG_PREF;+ LastGlyph->Flags |= KBTS_GLYPH_FLAG_PREF;++ PreBaseGlyphs[PreBaseGlyphCount++] = Glyph;+ PreBaseGlyphs[PreBaseGlyphCount++] = LastGlyph;++ // All of the glyphs written so far need to be flagged with cfar.+ // @Speed: Detect the Halant-Ra sequence in the FSM loop.+ for(kbts_glyph *PostRaGlyph = LastGlyph->Next;+ PostRaGlyph != OnePastLastSyllableGlyph;+ PostRaGlyph = PostRaGlyph->Next)+ {+ PostRaGlyph->Flags |= KBTS_GLYPH_FLAG_CFAR;+ }++ SawHalantRa = 1;+ }++ LastGlyph = Glyph;+ }++ while(PreBaseGlyphCount)+ {+ kbts_glyph *PreBaseGlyph = PreBaseGlyphs[--PreBaseGlyphCount];+ KBTS__DLLIST_REMOVE(PreBaseGlyph);+ PreBaseGlyph->Prev = OneBeforeSyllableGlyph;+ PreBaseGlyph->Next = OneBeforeSyllableGlyph->Next;+ PreBaseGlyph->Prev->Next = PreBaseGlyph->Next->Prev = PreBaseGlyph;+ }++ Result = OnePastLastSyllableGlyph;+ }+ } break;++ case KBTS_SHAPER_MYANMAR:+ {+ int NonCluster = 0;+ while(kbts__GlyphIsValid(Storage, Glyph) &&+ ((Glyph->SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_OTHER) ||+ (Glyph->SyllabicClass >= KBTS_MYANMAR_SYLLABIC_CLASS_COUNT)))+ {+ NonCluster = 1;+ }++ if(!NonCluster)+ {+ kbts_u8 State = 0;+ kbts_glyph *FirstGlyph = Glyph;+ while(kbts__GlyphIsValid(Storage, Glyph) &&+ (State < KBTS_MYANMAR_SYLLABIC_STATE_COUNT))+ {+ kbts_indic_syllabic_class Class = Glyph->SyllabicClass;++ State = kbts_MyanmarSyllabicTransition[Class][State];+ // @Incomplete: Remove this!+ State -= 1;++ Glyph = Glyph->Next;+ }++ if(State >= KBTS_MYANMAR_SYLLABIC_STATE_COUNT)+ {+ Glyph = Glyph->Prev;+ }+ if(Glyph == FirstGlyph)+ {+ Glyph = Glyph->Next;+ }++ Scratchpad->RealCluster = 1;+ }++ Result = Glyph;+ } break;+ }++ if(0)+ {+ OutOfMemory:;+ Scratchpad->Error = KBTS_SHAPE_ERROR_OUT_OF_MEMORY;+ }++ kbts__EndLifetime(&Lifetime);+ return Result;+}++static void kbts__EndCluster(kbts__shape_scratchpad *Scratchpad, kbts_shape_config *Config, kbts_glyph_storage *Storage)+{+ switch(Config->Shaper)+ {+ case KBTS_SHAPER_INDIC:+ if(kbts__GlyphIsValid(Storage, Storage->GlyphSentinel.Next))+ {+ // Final syllable reordering.+ // We are just copying Harfbuzz here, because I've read all the documentation I can and, frankly, I have no idea.+ kbts__feature *Pref = Config->Pref;++ kbts_u32 ViramaId = Config->Virama.Id;+ KBTS__FOR_GLYPH(Storage, Glyph)+ {+ // Harfbuzz tests for (ligated | multiplied) here.+ // I don't really get why, because, supposedly, all viramas should be+ // classified as halants regardless.+ if(ViramaId && (Glyph->Id == ViramaId))+ {+ Glyph->SyllabicClass = KBTS_INDIC_SYLLABIC_CLASS_HALANT;+ Glyph->Flags &= ~(KBTS_GLYPH_FLAG_LIGATURE | KBTS_GLYPH_FLAG_MULTIPLE_SUBSTITUTION);+ }+ else if(Glyph->Flags & KBTS_GLYPH_FLAG_LIGATURE)+ {+ // We can't know the syllabic classes of ligatures for sure.+ Glyph->SyllabicClass = KBTS_INDIC_SYLLABIC_CLASS_COUNT;+ }+ }++ // Locate the syllable base.+ kbts_glyph *BaseGlyph = (kbts_glyph *)&Storage->GlyphSentinel;+ {+ kbts_glyph *AfterPreBase = Storage->GlyphSentinel.Next;+ while(kbts__GlyphIsValid(Storage, AfterPreBase) &&+ (AfterPreBase->SyllabicPosition < KBTS__SYLLABIC_POSITION_SYLLABLE_BASE))+ {+ AfterPreBase = AfterPreBase->Next;+ }++ if(kbts__GlyphIsValid(Storage, AfterPreBase))+ {+ BaseGlyph = AfterPreBase;++ if(Pref && kbts__GlyphIsValid(Storage, AfterPreBase->Next))+ {+ // If we find a pre-base-reordering ra, then the base is probably right after it!+ kbts_glyph *AtGlyph = AfterPreBase->Next;+ while(kbts__GlyphIsValid(Storage, AtGlyph) &&+ !(AtGlyph->Flags & KBTS_GLYPH_FLAG_PREF))+ {+ AtGlyph = AtGlyph->Next;+ }++ // If we are not a consonant, then we are attached to a consonant.+ // If we are a pref-able consonant, but we did not form a pref, then we should be right after the base.+ // Either way, we are very close to the base.+ kbts_glyph *Prefable = AtGlyph; // Read like "pref-able". :)+ if(kbts__GlyphIsValid(Storage, Prefable) &&+ (!(Prefable->Flags & KBTS_GLYPH_FLAG_GENERATED_BY_GSUB) ||+ !(Prefable->Flags & KBTS_GLYPH_FLAG_LIGATURE) ||+ (Prefable->Flags & KBTS_GLYPH_FLAG_MULTIPLE_SUBSTITUTION)))+ {+ while(kbts__GlyphIsValid(Storage, Prefable) &&+ (Prefable->SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_HALANT))+ {+ Prefable = Prefable->Next;+ }++ if(kbts__GlyphIsValid(Storage, Prefable))+ {+ Prefable->SyllabicPosition = KBTS__SYLLABIC_POSITION_SYLLABLE_BASE;+ BaseGlyph = Prefable;+ // Fall through to the Malayalam test.+ }+ }+ }++ if(Config->Script == KBTS_SCRIPT_MALAYALAM)+ {+ // In Malayalam, the base is after below-base forms.+ // (We actually just give all below-base forms the base pos.)+ // @Speed: This would be way simpler with a null sentinel at the end of Glyphs!+ kbts_glyph *AtGlyph = BaseGlyph->Next;+ while(kbts__GlyphIsValid(Storage, AtGlyph))+ {+ while(kbts__GlyphIsValid(Storage, AtGlyph) &&+ KBTS__IN_SET(AtGlyph->SyllabicClass, KBTS__SET32((KBTS_INDIC_SYLLABIC_CLASS_ZWJ)+ (KBTS_INDIC_SYLLABIC_CLASS_ZWNJ))))+ {+ AtGlyph = AtGlyph->Next;+ }++ if(kbts__GlyphIsValid(Storage, AtGlyph) &&+ (AtGlyph->SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_HALANT))+ {+ AtGlyph = AtGlyph->Next;+ }+ else+ {+ break;+ }++ while(kbts__GlyphIsValid(Storage, AtGlyph) &&+ KBTS__IN_SET(AtGlyph->SyllabicClass, KBTS__SET32((KBTS_INDIC_SYLLABIC_CLASS_ZWJ)+ (KBTS_INDIC_SYLLABIC_CLASS_ZWNJ))))+ {+ AtGlyph = AtGlyph->Next;+ }++ if(kbts__GlyphIsValid(Storage, AtGlyph))+ {+ if(kbts__SyllabicClassIsConsonant(AtGlyph->SyllabicClass) &&+ (AtGlyph->SyllabicPosition == KBTS__SYLLABIC_POSITION_BELOWBASE_CONSONANT))+ {+ AtGlyph->SyllabicPosition = KBTS__SYLLABIC_POSITION_SYLLABLE_BASE;+ BaseGlyph = AtGlyph;+ // Do not break; keep matching below-base forms.+ }+ }+ }+ }+ }++ if(kbts__GlyphIsValid(Storage, BaseGlyph) &&+ kbts__GlyphIsValid(Storage, BaseGlyph->Prev) &&+ (BaseGlyph->SyllabicPosition > KBTS__SYLLABIC_POSITION_SYLLABLE_BASE))+ {+ BaseGlyph = BaseGlyph->Prev;+ }++ if(!kbts__GlyphIsValid(Storage, BaseGlyph) &&+ (BaseGlyph->Prev->SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_ZWJ))+ {+ BaseGlyph = BaseGlyph->Prev;+ }++ if(kbts__GlyphIsValid(Storage, BaseGlyph))+ {+ while(kbts__GlyphIsValid(Storage, BaseGlyph->Prev) &&+ KBTS__IN_SET(BaseGlyph->SyllabicClass, KBTS__SET32((KBTS_INDIC_SYLLABIC_CLASS_NUKTA)+ (KBTS_INDIC_SYLLABIC_CLASS_HALANT))))+ {+ BaseGlyph = BaseGlyph->Prev;+ }+ }+ }++ // Reorder matras.+ if(kbts__GlyphIsValid(Storage, BaseGlyph->Prev) &&+ (Storage->GlyphSentinel.Prev != Storage->GlyphSentinel.Next) /* GlyphCount > 1 */)+ {+ kbts_glyph *FirstGlyph = Storage->GlyphSentinel.Next;+ kbts_glyph *To = BaseGlyph->Prev;+ if(!kbts__GlyphIsValid(Storage, BaseGlyph))+ {+ To = To->Prev;+ }++ if((Config->Script != KBTS_SCRIPT_MALAYALAM) && (Config->Script != KBTS_SCRIPT_TAMIL))+ {+ kbts_glyph *LastGlyph = To->Next;++ for(;;)+ {+ while((To != FirstGlyph) &&+ !KBTS__IN_SET(To->SyllabicClass, KBTS__SET32((KBTS_INDIC_SYLLABIC_CLASS_MATRA)+ (KBTS_INDIC_SYLLABIC_CLASS_MATRA_POST)+ (KBTS_INDIC_SYLLABIC_CLASS_HALANT))))+ {+ LastGlyph = To;+ To = To->Prev;+ }++ if((To->SyllabicClass != KBTS_INDIC_SYLLABIC_CLASS_HALANT) ||+ (To->SyllabicPosition == KBTS__SYLLABIC_POSITION_PREBASE_MATRA))+ {+ // We have nothing to move.+ To = FirstGlyph;++ break;+ }+ else if((To != FirstGlyph) &&+ kbts__GlyphIsValid(Storage, LastGlyph) &&+ (LastGlyph->SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_ZWJ))+ {+ // Zwj+Halant cancels matra movement when the Halant is not attached to the matra.+ To = To->Prev;+ }+ else+ {+ break;+ }+ }+ }++ if((To != FirstGlyph) &&+ (To->SyllabicPosition != KBTS__SYLLABIC_POSITION_PREBASE_MATRA))+ {+ for(kbts_glyph *Matra = To->Prev;+ kbts__GlyphIsValid(Storage, Matra);+ )+ {+ kbts_glyph *MatraPrev = Matra->Prev;++ if(Matra->SyllabicPosition == KBTS__SYLLABIC_POSITION_PREBASE_MATRA)+ {+ KBTS__DLLIST_REMOVE(Matra);+ KBTS__DLLIST_INSERT_AFTER(Matra, To);++ To = Matra->Prev;+ }++ Matra = MatraPrev;+ }+ }+ }++ // Reorder reph.+ // We should only reorder reph when it is a single Repha glyph, and not a Ra sequence.+ kbts_glyph *First = Storage->GlyphSentinel.Next;+ kbts_glyph *Second = First->Next;+ if((First->SyllabicPosition == KBTS__SYLLABIC_POSITION_RA_TO_BECOME_REPH) &&+ kbts__GlyphIsValid(Storage, Second) &&+ (Second->SyllabicPosition != KBTS__SYLLABIC_POSITION_RA_TO_BECOME_REPH))+ {+ kbts__reph_position RephPosition = Config->IndicScriptProperties.RephPosition;+ kbts_glyph *To = 0;++ for(kbts_glyph *Glyph = First;+ Glyph != BaseGlyph;+ )+ {+ kbts_glyph *Next = Glyph->Next;++ if(Glyph->SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_HALANT)+ {+ To = Glyph;++ if(Next != BaseGlyph)+ {+ kbts_u8 NextClass = Next->SyllabicClass;++ if((NextClass == KBTS_INDIC_SYLLABIC_CLASS_ZWJ) ||+ (NextClass == KBTS_INDIC_SYLLABIC_CLASS_ZWNJ))+ {+ To = Next;+ }+ }++ break;+ }++ Glyph = Next;+ }++ if(!To)+ {+ // @Cleanup: We can merge these loops.+ if(RephPosition == KBTS__REPH_POSITION_AFTER_SUBJOINED)+ {+ for(kbts_glyph *Glyph = BaseGlyph;+ kbts__GlyphIsValid(Storage, Glyph);+ Glyph = Glyph->Next)+ {+ kbts_u8 SyllabicPosition = Glyph->SyllabicPosition;++ if(KBTS__IN_SET(SyllabicPosition, KBTS__SET32((KBTS__SYLLABIC_POSITION_POSTBASE_CONSONANT)+ (KBTS__SYLLABIC_POSITION_AFTER_POST)+ (KBTS__SYLLABIC_POSITION_SMVD))))+ {+ To = Glyph->Prev;++ break;+ }+ }+ }+ else if(RephPosition == KBTS__REPH_POSITION_AFTER_MAIN)+ {+ for(kbts_glyph *Glyph = BaseGlyph;+ kbts__GlyphIsValid(Storage, Glyph);+ Glyph = Glyph->Next)+ {+ if(Glyph->SyllabicPosition > KBTS__SYLLABIC_POSITION_AFTER_MAIN)+ {+ To = Glyph->Prev;++ break;+ }+ }+ }+ }++ if(!To)+ {+ // As a fallback, move reph to the end of the syllable.+ for(kbts_glyph *Glyph = Storage->GlyphSentinel.Prev;+ kbts__GlyphIsValid(Storage, Glyph);+ Glyph = Glyph->Prev)+ {+ if(Glyph->SyllabicPosition != KBTS__SYLLABIC_POSITION_SMVD)+ {+ To = Glyph;++ break;+ }+ }++ // Matras will still come after reph.+ kbts_glyph *Glyph = To;+ if(Glyph->SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_HALANT)+ {+ for(kbts_glyph *Matra = BaseGlyph->Next;+ Matra != To;+ Matra = Matra->Next)+ {+ kbts_u8 Class = Matra->SyllabicClass;++ if(KBTS__IN_SET(Class, KBTS__SET32((KBTS_INDIC_SYLLABIC_CLASS_MATRA)+ (KBTS_INDIC_SYLLABIC_CLASS_MATRA_POST)+ (KBTS_INDIC_SYLLABIC_CLASS_CONSONANT_MEDIAL))))+ {+ To = To->Prev;+ }+ }+ }+ }++ if(To)+ {+ // Do the reorder!+ KBTS__DLLIST_REMOVE(First);+ KBTS__DLLIST_INSERT_AFTER(First, To);+ }+ }++ // Reorder pre-base-reordering consonants.+ if(Pref)+ {+ First = Storage->GlyphSentinel.Next;+ kbts_glyph *PrefGlyph = 0;++ for(kbts_glyph *Glyph = BaseGlyph->Next;+ kbts__GlyphIsValid(Storage, Glyph);+ Glyph = Glyph->Next)+ {+ if(Glyph->Flags & KBTS_GLYPH_FLAG_PREF)+ {+ PrefGlyph = Glyph;++ break;+ }+ }++ if(PrefGlyph)+ {+ // Harfbuzz says the ideal is to check that this glyph was generated by the pref feature specifically,+ // but then just uses a generic flag like this.+ // The ideal solution would not be very difficult to implement!+ if(PrefGlyph->Flags & KBTS_GLYPH_FLAG_GENERATED_BY_GSUB)+ {+ kbts_glyph *To = First;++ kbts_glyph *Last = BaseGlyph;+ for(kbts_glyph *Glyph = BaseGlyph->Prev;+ kbts__GlyphIsValid(Storage, Glyph);+ Glyph = Glyph->Prev)+ {+ kbts_u8 Class = Glyph->SyllabicClass;++ if(KBTS__IN_SET(Class, KBTS__SET32((KBTS_INDIC_SYLLABIC_CLASS_MATRA)+ (KBTS_INDIC_SYLLABIC_CLASS_MATRA_POST)+ (KBTS_INDIC_SYLLABIC_CLASS_CONSONANT_MEDIAL)+ (KBTS_INDIC_SYLLABIC_CLASS_HALANT))))+ {+ To = Last;++ break;+ }++ Last = Glyph;+ }++ if(To != First)+ {+ kbts_glyph *Prev = To->Prev;+ kbts_u8 CurrentClass = To->SyllabicClass;++ if((Prev->SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_HALANT) &&+ KBTS__IN_SET(CurrentClass, KBTS__SET32((KBTS_INDIC_SYLLABIC_CLASS_ZWJ)+ (KBTS_INDIC_SYLLABIC_CLASS_ZWNJ))))+ {+ To = To->Next;+ }+ }++ // Do the reorder!+ KBTS__DLLIST_REMOVE(PrefGlyph);+ KBTS__DLLIST_INSERT_BEFORE(PrefGlyph, To);+ }+ }+ }++ { // Mark matras at the beginning of a word for init application.+ // It is tempting to check for this at the same time as the reph reordering, but glyphs could have been+ // reordered since then and the reordering procedure is clearly defined to happen in sequential steps.+ First = Storage->GlyphSentinel.Next; // I don't think this needs to be reloaded, but you never know.++ if((First->SyllabicPosition == KBTS__SYLLABIC_POSITION_PREBASE_MATRA) && Scratchpad->ClusterAtStartOfWord)+ {+ First->Flags |= KBTS_GLYPH_FLAG_INIT;+ }+ }+ }+ break;++ case KBTS_SHAPER_USE:+ {+ kbts_u64 PostBaseSet = KBTS__SET64((KBTS_USE_SYLLABIC_CLASS_CONS_FINAL_ABOVE) (KBTS_USE_SYLLABIC_CLASS_CONS_FINAL_BELOW)+ (KBTS_USE_SYLLABIC_CLASS_CONS_FINAL_MOD_ABOVE) (KBTS_USE_SYLLABIC_CLASS_CONS_FINAL_MOD_BELOW)+ (KBTS_USE_SYLLABIC_CLASS_CONS_FINAL_MOD_POST) (KBTS_USE_SYLLABIC_CLASS_CONS_MED_ABOVE)+ (KBTS_USE_SYLLABIC_CLASS_CONS_MED_BELOW) (KBTS_USE_SYLLABIC_CLASS_CONS_MED_POST)+ (KBTS_USE_SYLLABIC_CLASS_CONS_MED_PRE) (KBTS_USE_SYLLABIC_CLASS_VOWEL_ABOVE)+ (KBTS_USE_SYLLABIC_CLASS_VOWEL_BELOW) (KBTS_USE_SYLLABIC_CLASS_VOWEL_POST)+ (KBTS_USE_SYLLABIC_CLASS_VOWEL_PRE) (KBTS_USE_SYLLABIC_CLASS_VOWEL_MOD_ABOVE)+ (KBTS_USE_SYLLABIC_CLASS_VOWEL_MOD_BELOW) (KBTS_USE_SYLLABIC_CLASS_VOWEL_MOD_POST)+ (KBTS_USE_SYLLABIC_CLASS_VOWEL_MOD_PRE));+ kbts_u64 HalantSet = KBTS__SET64((KBTS_USE_SYLLABIC_CLASS_HALANT)+ (KBTS_USE_SYLLABIC_CLASS_HALANT_OR_VOWEL_MODIFIER)+ (KBTS_USE_SYLLABIC_CLASS_INVISIBLE_STACKER));++ // In the reorderings below, we check for halants because that's what Harfbuzz does.+ // Nowhere does Microsoft mention that halants should block reorderings!+ kbts_glyph *Repha = Storage->GlyphSentinel.Next;+ if((Repha->UseClass == KBTS_USE_SYLLABIC_CLASS_REPHA) ||+ (Repha->Flags & KBTS_GLYPH_FLAG_RPHF))+ {+ kbts_glyph *To = Repha->Next;+ for(;+ kbts__GlyphIsValid(Storage, To);+ To = To->Next)+ {+ // Microsoft says that rephas are reordered "after a following full base", which is needlessly vague.+ // Harfbuzz reorders them in front of the first post-base glyph.+ if(KBTS__IN_SET64(To->UseClass, PostBaseSet) ||+ (!(To->Flags & KBTS_GLYPH_FLAG_LIGATURE) &&+ KBTS__IN_SET64(To->UseClass, HalantSet)))+ {+ break;+ }+ }++ KBTS__DLLIST_REMOVE(Repha);+ KBTS__DLLIST_INSERT_BEFORE(Repha, To);+ }++ {+ // Microsoft says that pre-base vowels and vowel modifiers should be reordered "before the base glyph+ // and, if present, before a pre-base glyph reordered via the 'pref' feature".+ // In practice, we tag 'pref'-generated glyphs with the VOWEL_PRE class so that they get reordered here.+ // Note that the final reordered glyphs end up backwards from their original order.+ kbts_glyph *PreBaseVowels[16]; // @Robustness: How many vowels can there realistically be in a single cluster?+ kbts_un PreBaseVowelCount = 0;+ kbts_u64 SawBase = 0;+ for(kbts_glyph *Glyph = Storage->GlyphSentinel.Prev;+ kbts__GlyphIsValid(Storage, Glyph);+ Glyph = Glyph->Prev)+ {+ SawBase |= KBTS__IN_SET64(Glyph->UseClass, KBTS__SET64((KBTS_USE_SYLLABIC_CLASS_BASE)+ (KBTS_USE_SYLLABIC_CLASS_BASE_OTHER)+ (KBTS_USE_SYLLABIC_CLASS_BASE_NUM)));++ kbts_u32 Flags = Glyph->Flags;+ // Only accept the first glyphs produced by multiple substitutions.+ if(((Flags & KBTS_GLYPH_FLAG_FIRST_IN_MULTIPLE_SUBSTITUTION) ||+ !(Flags & KBTS_GLYPH_FLAG_MULTIPLE_SUBSTITUTION)) &&+ (KBTS__IN_SET64(Glyph->UseClass, KBTS__SET64((KBTS_USE_SYLLABIC_CLASS_VOWEL_PRE)+ (KBTS_USE_SYLLABIC_CLASS_VOWEL_MOD_PRE))) ||+ (Flags & KBTS_GLYPH_FLAG_PREF)))+ {+ if(PreBaseVowelCount < KBTS__ARRAY_LENGTH(PreBaseVowels))+ {+ PreBaseVowels[PreBaseVowelCount++] = Glyph;+ }+ }+ else if(!(Glyph->Flags & KBTS_GLYPH_FLAG_LIGATURE) &&+ KBTS__IN_SET64(Glyph->UseClass, HalantSet))+ {+ // Reordering stops at halants, apparently.+ // We want to write the vowels in the reverse order they appear in the glyph sequence.+ // Since we are iterating backwards, they already _are_ backwards in the PreBaseVowels array,+ // so there's no need to do anything.+ kbts_glyph *InsertAfter = Glyph;+ KBTS__FOR(PreBaseVowelIndex, 0, PreBaseVowelCount)+ {+ kbts_glyph *PreBaseVowel = PreBaseVowels[PreBaseVowelIndex];++ KBTS__DLLIST_REMOVE(PreBaseVowel);+ KBTS__DLLIST_INSERT_AFTER(PreBaseVowel, InsertAfter);+ InsertAfter = PreBaseVowel;+ }+ PreBaseVowelCount = 0;++ // Valid bases only show up before halants.+ SawBase = 0;+ }+ }++ kbts_glyph *DottedCircleInsertBefore = Storage->GlyphSentinel.Next;++ { // Flush the rest of the vowels.+ kbts_glyph *InsertAfter = (kbts_glyph *)&Storage->GlyphSentinel;+ KBTS__FOR(PreBaseVowelIndex, 0, PreBaseVowelCount)+ {+ kbts_glyph *PreBaseVowel = PreBaseVowels[PreBaseVowelIndex];++ KBTS__DLLIST_REMOVE(PreBaseVowel);+ KBTS__DLLIST_INSERT_AFTER(PreBaseVowel, InsertAfter);++ InsertAfter = PreBaseVowel;+ }+ }++ if(Scratchpad->RealCluster && !SawBase && Config->DottedCircle.Id)+ {+ kbts_glyph *DottedCircle = kbts__InsertGlyphBefore(Storage, DottedCircleInsertBefore, &Config->DottedCircle);+ if(!DottedCircle)+ {+ goto OutOfMemory;+ }++ DottedCircle->UserIdOrCodepointIndex = DottedCircleInsertBefore->UserIdOrCodepointIndex;+ }+ }+ } break;++ case KBTS_SHAPER_MYANMAR:+ if(Scratchpad->RealCluster)+ {+ kbts_glyph *BaseGlyph = (kbts_glyph *)&Storage->GlyphSentinel;+ kbts_glyph *First = BaseGlyph->Next;+ kbts_glyph *Second = First->Next;+ kbts_glyph *Third = Second->Next;+ kbts_glyph *OnePastReph = First;++ kbts_un MinimumGlyphCount = 0;++ if(kbts__GlyphIsValid(Storage, First))+ {+ MinimumGlyphCount += 1;++ if(kbts__GlyphIsValid(Storage, Second))+ {+ MinimumGlyphCount += 1;++ if(kbts__GlyphIsValid(Storage, Third))+ {+ MinimumGlyphCount += 1;+ }+ }+ }++ if((MinimumGlyphCount == 3) &&+ (First->SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_RA) &&+ (Second->SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_ASAT) &&+ (Third->SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_HALANT))+ {+ First->SyllabicPosition = KBTS__SYLLABIC_POSITION_AFTER_MAIN;+ Second->SyllabicPosition = KBTS__SYLLABIC_POSITION_AFTER_MAIN;+ Third->SyllabicPosition = KBTS__SYLLABIC_POSITION_AFTER_MAIN;++ OnePastReph = Third->Next;+ BaseGlyph = First;+ }++ kbts_u64 BaseSet = KBTS__SET64((KBTS_INDIC_SYLLABIC_CLASS_CONSONANT)+ (KBTS_INDIC_SYLLABIC_CLASS_CONSONANT_WITH_STACKER)+ (KBTS_INDIC_SYLLABIC_CLASS_RA)+ (KBTS_INDIC_SYLLABIC_CLASS_VOWEL)+ (KBTS_INDIC_SYLLABIC_CLASS_PLACEHOLDER)+ (KBTS_INDIC_SYLLABIC_CLASS_DOTTED_CIRCLE));++ // Scan for a non-reph base glyph.+ for(kbts_glyph *Glyph = OnePastReph;+ kbts__GlyphIsValid(Storage, Glyph);+ Glyph = Glyph->Next)+ {+ kbts_indic_syllabic_class Class = Glyph->SyllabicClass;++ if(!kbts__GlyphIsValid(Storage, BaseGlyph) &&+ KBTS__IN_SET64(Class, BaseSet))+ {+ BaseGlyph = Glyph;++ break;+ }+ }++ // Otherwise, reph can be the base.+ // @Cleanup: I'm pretty sure this is @Duplication with the reph check above.+ if(!kbts__GlyphIsValid(Storage, BaseGlyph) &&+ (OnePastReph != First))+ {+ BaseGlyph = First;+ }++ if(kbts__GlyphIsValid(Storage, BaseGlyph))+ {+ kbts__syllabic_position LastPosition = KBTS__SYLLABIC_POSITION_SYLLABLE_BASE;+ kbts__syllabic_position SectionPosition = KBTS__SYLLABIC_POSITION_AFTER_MAIN;+ kbts_glyph *LastPreBaseMatra = (kbts_glyph *)&Storage->GlyphSentinel;+ for(kbts_glyph *Glyph = BaseGlyph->Next;+ kbts__GlyphIsValid(Storage, Glyph);+ )+ {+ kbts_glyph *Next = Glyph->Next; // Make sure we preserve the link when reversing.+ kbts__syllabic_position Position = SectionPosition;++ switch(Glyph->SyllabicClass)+ {+ case KBTS_INDIC_SYLLABIC_CLASS_MEDIAL_RA:+ Position = KBTS__SYLLABIC_POSITION_PREBASE_CONSONANT;+ break;++ case KBTS_INDIC_SYLLABIC_CLASS_VOWEL_PRE:+ {+ Position = KBTS__SYLLABIC_POSITION_PREBASE_MATRA;++ // According to Unicode 15.0:+ // For combining characters placed to the left of a base character, the combining characters start from the base+ // character and are arranged leftward.+ // Since these guys will get reordered into being pre-base, we need to flip them.+ if(kbts__GlyphIsValid(Storage, LastPreBaseMatra))+ {+ kbts__DllistReverseSublist(LastPreBaseMatra, Glyph->Next);+ }+ else+ {+ // When we reverse, this will become the "last" pre-base matra again, so we only need to set it once.+ LastPreBaseMatra = Glyph;+ }+ } break;++ case KBTS_INDIC_SYLLABIC_CLASS_VARIATION_SELECTOR:+ Position = LastPosition;+ break;++ case KBTS_INDIC_SYLLABIC_CLASS_VOWEL_BELOW:+ if(Position == KBTS__SYLLABIC_POSITION_AFTER_MAIN)+ {+ Position = KBTS__SYLLABIC_POSITION_BELOWBASE_CONSONANT;+ }+ else if(Position == KBTS__SYLLABIC_POSITION_BELOWBASE_CONSONANT)+ {+ Position = SectionPosition;+ }+ break;++ case KBTS_INDIC_SYLLABIC_CLASS_VEDIC_SIGN:+ if(Position == KBTS__SYLLABIC_POSITION_BELOWBASE_CONSONANT)+ {+ Position = KBTS__SYLLABIC_POSITION_BEFORE_SUBJOINED;+ }+ break;+ }++ if((SectionPosition == KBTS__SYLLABIC_POSITION_BELOWBASE_CONSONANT) && (Glyph->SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_VEDIC_SIGN))+ {+ SectionPosition = KBTS__SYLLABIC_POSITION_AFTER_SUBJOINED;+ Position = SectionPosition;+ }++ Glyph->SyllabicPosition = Position;+ LastPosition = Position;+ Glyph = Next;+ }+ }++ if(MinimumGlyphCount > 1)+ {+ KBTS__DLLIST_SORT(Storage->GlyphSentinel.Next, (kbts_glyph *)&Storage->GlyphSentinel, SyllabicPosition);++ #ifdef KBTS_SANITY_CHECK+ {+ kbts_glyph *Left = C->GlyphSentinel.Next;+ kbts_glyph *Right = Left->Next;+ while(kbts__GlyphIsValid(C, Right))+ {+ kbts_glyph *Next = Right->Next;++ KBTS_ASSERT(Left->SyllabicPosition <= Right->SyllabicPosition);++ Left = Right;+ Right = Next;+ }+ }+ #endif+ }+ } break;+ }++ if(0)+ {+ OutOfMemory:;+ Scratchpad->Error = KBTS_SHAPE_ERROR_OUT_OF_MEMORY;+ }+}++static void *kbts__PointerPush(char **Pointer, kbts_un Size, kbts_un Align)+{+ char *At = *Pointer;+ char *Aligned = KBTS__ALIGN_POINTER(char, At, Align);+ *Pointer = Aligned + Size;++ void *Result = Aligned;+ return Result;+}+#define kbts__PointerPushType(Pointer, Type) (Type *)kbts__PointerPush((Pointer), sizeof(Type), KBTS_ALIGNOF(Type))+#define kbts__PointerPushArray(Pointer, Type, Count) (Type *)kbts__PointerPush((Pointer), sizeof(Type) * (Count), KBTS_ALIGNOF(Type))++static int kbts__ReadOp(kbts__shape_scratchpad *Scratchpad, kbts_shape_config *Config, kbts__op_kind End)+{+ KBTS_INSTRUMENT_FUNCTION_BEGIN;+ int Result = 0;++ if(Config)+ {+ kbts__op_list *OpList = &Config->OpList;++ if(Scratchpad->Ip < OpList->OpCount)+ {+ kbts__op_kind Kind = OpList->Ops[Scratchpad->Ip++];++ if((Kind == KBTS__OP_KIND_GSUB_FEATURES_WITH_USER) ||+ (Kind == KBTS__OP_KIND_GSUB_FEATURES) ||+ (Kind == KBTS__OP_KIND_GPOS_FEATURES))+ {+ kbts__feature_stage *FeatureStage = &OpList->FeatureStages[Scratchpad->FeatureStagesRead++];+ Scratchpad->OpFeatures = &FeatureStage->Features;++ // We only have one GPOS_FEATURES op per op list, so it's fine to add user features like this.+ if((Kind == KBTS__OP_KIND_GSUB_FEATURES_WITH_USER) ||+ (Kind == KBTS__OP_KIND_GPOS_FEATURES))+ {+ if(Kind == KBTS__OP_KIND_GSUB_FEATURES_WITH_USER)+ {+ Kind = KBTS__OP_KIND_GSUB_FEATURES;+ }++ KBTS__FOR(WordIndex, 0, KBTS__ARRAY_LENGTH(Scratchpad->ScratchFeatures.Flags))+ {+ Scratchpad->ScratchFeatures.Flags[WordIndex] = Scratchpad->UserFeatures.Flags[WordIndex] | FeatureStage->Features.Flags[WordIndex];+ }++ Scratchpad->OpFeatures = &Scratchpad->ScratchFeatures;+ }+ }++ Scratchpad->OpKind = Kind;+ Result = (Kind != End);+ }+ }++ KBTS_INSTRUMENT_FUNCTION_END;+ return Result;+}++static kbts_shape_config *kbts__PlaceShapeConfig(kbts_font *Font, kbts_script Script, kbts_language Language, void *Memory, kbts_un *Size)+{+ kbts_shape_config *Result = 0;+ kbts_shape_config DummyConfig;+ char *MemoryAt = (char *)Memory;++ if(Font)+ {+ Result = kbts__PointerPushType(&MemoryAt, kbts_shape_config);+ if(!Memory)+ {+ Result = &DummyConfig;+ }++ KBTS_MEMSET(Result, 0, sizeof(*Result));++ Result->Font = Font;+ Result->Script = Script;+ Result->Language = Language;++ kbts__gsub_gpos *ShapingTables[2] = {+ kbts__BlobTableDataType(Font->Blob, KBTS_BLOB_TABLE_ID_GSUB, kbts__gsub_gpos),+ kbts__BlobTableDataType(Font->Blob, KBTS_BLOB_TABLE_ID_GPOS, kbts__gsub_gpos),+ };++ kbts__gsub_gpos *Gsub = ShapingTables[0];++ // Find the appropriate language system in GSUB/GPOS.+ kbts__script_properties *ScriptProperties = &kbts__ScriptProperties[Script];+ int FoundScriptIsIndic3 = 0;++ KBTS__FOR(ShapingTableIndex, 0, KBTS_SHAPING_TABLE_COUNT)+ {+ kbts__gsub_gpos *ShapingTable = ShapingTables[ShapingTableIndex];+ if(ShapingTable)+ {+ kbts__script_list *ScriptList = KBTS__POINTER_OFFSET(kbts__script_list, ShapingTable, ShapingTable->ScriptListOffset);++ kbts__langsys *ChosenLangsys = 0;+ kbts_u32 DesiredTag = ScriptProperties->Tag;++ KBTS__FOR(ScriptIndex, 0, ScriptList->Count)+ {+ kbts__script_pointer ThisScript = kbts__GetScript(ScriptList, ScriptIndex);+ kbts_u32 Tag = ThisScript.Tag;++ // The OpenType spec does not define or even mention "Indic3" scripts at all.+ // Nevertheless, Harfbuzz at least checks for '3' at the end of script tags, and, if one exists, they choose USE.+ int Indic3 = (ThisScript.Tag >> 24) == '3';+ kbts_u32 MatchMask = Indic3 ? 0xFFFFFF : 0xFFFFFFFF;+ int PerfectMatch = !((Tag ^ DesiredTag) & MatchMask);+ if(!ScriptIndex || PerfectMatch || (Tag == KBTS_FOURCC('D', 'F', 'L', 'T')))+ {+ kbts__langsys *Langsys = kbts__GetDefaultLangsys(ThisScript.Script);+ KBTS__FOR(LangsysIndex, 0, ThisScript.Script->Count)+ {+ kbts__langsys_pointer LangsysPointer = kbts__GetLangsys(ThisScript.Script, LangsysIndex);++ if(LangsysPointer.Tag == Language)+ {+ Langsys = LangsysPointer.Langsys;+ break;+ }+ }++ // It is tempting to try to look for another script if the one we want has no langsys.+ // However, it is possible for a script to purposefully have no langsys at all. In that case,+ // the shaper should not apply any GSUB features.+ // So, store the result _regardless_ of whether Langsys is null or not.+ ChosenLangsys = Langsys;+ if(ShapingTableIndex == KBTS_SHAPING_TABLE_GSUB)+ {+ // Apparently, it is allowed to have script-specific GSUB tables, and a huge DFLT GPOS table.+ FoundScriptIsIndic3 = Indic3;+ }+ // And then get out if we found the appropriate script, even if the langsys is null!+ if(PerfectMatch)+ {+ break;+ }+ }+ }++ Result->Langsys[ShapingTableIndex] = ChosenLangsys;+ }+ }++ Result->IndicScriptProperties = kbts__IndicScriptProperties(Script);+ Result->Shaper = FoundScriptIsIndic3 ? KBTS_SHAPER_USE : ScriptProperties->Shaper;+ Result->OpList = *kbts__ShaperOpLists[Result->Shaper];++ Result->Features = KBTS__ZERO_TYPE(kbts__feature_set);+ KBTS__FOR(StageIndex, 0, Result->OpList.FeatureStageCount)+ {+ kbts__feature_stage *Stage = &Result->OpList.FeatureStages[StageIndex];++ KBTS__FOR(WordIndex, 0, KBTS__ARRAY_LENGTH(Result->Features.Flags))+ {+ Result->Features.Flags[WordIndex] |= Stage->Features.Flags[WordIndex];+ }+ }++ kbts__feature *Rclt = 0;+ kbts__feature_set SyllableFeatureSet = {{KBTS__FEATURE_FLAG0(rphf) | KBTS__FEATURE_FLAG0(blwf) | KBTS__FEATURE_FLAG0(half) | KBTS__FEATURE_FLAG0(pstf) | KBTS__FEATURE_FLAG0(pref),+ 0, KBTS__FEATURE_FLAG2(rclt) | KBTS__FEATURE_FLAG2(locl), KBTS__FEATURE_FLAG3(vatu)}};+ kbts__iterate_features IterateFeatures = kbts__IterateFeatures(Result, KBTS_SHAPING_TABLE_GSUB, SyllableFeatureSet);+ while(kbts__NextFeature(&IterateFeatures))+ {+ switch(IterateFeatures.CurrentFeatureTag)+ {+ case KBTS_FEATURE_TAG_blwf: Result->Blwf = IterateFeatures.Feature; break;+ case KBTS_FEATURE_TAG_pref: Result->Pref = IterateFeatures.Feature; break;+ case KBTS_FEATURE_TAG_pstf: Result->Pstf = IterateFeatures.Feature; break;+ case KBTS_FEATURE_TAG_locl: Result->Locl = IterateFeatures.Feature; break;+ case KBTS_FEATURE_TAG_rphf: Result->Rphf = IterateFeatures.Feature; break;+ case KBTS_FEATURE_TAG_half: Result->Half = IterateFeatures.Feature; break;+ case KBTS_FEATURE_TAG_vatu: Result->Vatu = IterateFeatures.Feature; break;+ case KBTS_FEATURE_TAG_rclt: Rclt = IterateFeatures.Feature; break;+ }+ }++ if((Result->Shaper == KBTS_SHAPER_ARABIC) && !Rclt)+ {+ Result->OpList = kbts__OpList_ArabicNoRclt;+ }++ if(Result->IndicScriptProperties.ViramaCodepoint)+ {+ kbts__shape_scratchpad DummyScratchpad = KBTS__ZERO;+ kbts_glyph_storage DummyStorage = KBTS__ZERO;+ KBTS__DLLIST_SENTINEL_INIT(&DummyStorage.GlyphSentinel);+ KBTS__DLLIST_SENTINEL_INIT(&DummyStorage.FreeGlyphSentinel);++ // Bake the locl-ized virama.+ kbts_glyph Virama = kbts_CodepointToGlyph(Font, (int)Result->IndicScriptProperties.ViramaCodepoint, 0, 0);+ Result->Virama = kbts__Substitute1(&DummyScratchpad, Result, &DummyStorage, kbts__GetLookupList(Gsub), Result->Locl, KBTS__SKIP_FLAG_ZWNJ | KBTS__SKIP_FLAG_ZWJ, &Virama);+ }++ if((Result->Script == KBTS_SCRIPT_THAI) || (Result->Script == KBTS_SCRIPT_LAO))+ {+ kbts_u32 NikhahitCodepoint = (Result->Script == KBTS_SCRIPT_THAI) ? 0xE4D : 0xECD;+ kbts_u32 SaraAaCodepoint = (Result->Script == KBTS_SCRIPT_THAI) ? 0xE32 : 0xEB2;+ Result->Nikhahit = kbts_CodepointToGlyph(Font, (int)NikhahitCodepoint, 0, 0);+ Result->SaraAa = kbts_CodepointToGlyph(Font, (int)SaraAaCodepoint, 0, 0);+ }++ Result->DottedCircle = kbts_CodepointToGlyph(Font, 0x25CC, 0, 0);+ Result->Whitespace = kbts_CodepointToGlyph(Font, ' ', 0, 0);++ if(ShapingTables[KBTS_SHAPING_TABLE_GSUB] || ShapingTables[KBTS_SHAPING_TABLE_GPOS])+ { // Initialize the per-feature lookup lists.+ kbts__baked_feature_stage *BakedStages = kbts__PointerPushArray(&MemoryAt, kbts__baked_feature_stage, Result->OpList.FeatureStageCount);++ kbts_un FeatureStageIndex = 0;+ KBTS__FOR(OpIndex, 0, Result->OpList.OpCount)+ {+ kbts__op_kind Op = Result->OpList.Ops[OpIndex];+ int UserFeaturesAllowed = KBTS__IN_SET(Op, KBTS__SET32((KBTS__OP_KIND_GSUB_FEATURES_WITH_USER)+ (KBTS__OP_KIND_GPOS_FEATURES)));++ if(KBTS__IN_SET(Op, KBTS__SET32((KBTS__OP_KIND_GSUB_FEATURES)+ (KBTS__OP_KIND_GSUB_FEATURES_WITH_USER)+ (KBTS__OP_KIND_GPOS_FEATURES))))+ {+ kbts__feature_stage *FeatureStage = &Result->OpList.FeatureStages[FeatureStageIndex];+ kbts_shaping_table ShapingTable = (kbts_shaping_table)((Op == KBTS__OP_KIND_GPOS_FEATURES) ? KBTS_SHAPING_TABLE_GPOS : KBTS_SHAPING_TABLE_GSUB);+ kbts__gsub_gpos *GsubGpos = ShapingTables[ShapingTable];+ kbts__langsys *Langsys = Result->Langsys[ShapingTable];+ kbts_un BakedFeatureCount = 0;+ kbts_un BakedFeatureLookupIndexCount = 0;++ kbts__baked_feature_stage *BakedStage = &BakedStages[FeatureStageIndex];++ if(GsubGpos && Langsys)+ {+ kbts__feature_list *FeatureList = KBTS__POINTER_OFFSET(kbts__feature_list, GsubGpos, GsubGpos->FeatureListOffset);+ kbts_u16 *FeatureIndices = KBTS__POINTER_AFTER(kbts_u16, Langsys);+ kbts__baked_feature *BakedFeatures;++ // @Speed: Maybe we don't care about fragmentation and we just allocate Langsys->FeatureIndexCount in advance?+ KBTS__FOR(FeatureIndexIndex, 0, Langsys->FeatureIndexCount)+ {+ kbts_un FeatureIndex = FeatureIndices[FeatureIndexIndex];+ kbts__feature_pointer Feature = kbts__GetFeature(FeatureList, FeatureIndex);++ kbts_u32 FeatureId = kbts__FeatureTagToId(Feature.Tag);++ if(Feature.Feature->LookupIndexCount &&+ ((UserFeaturesAllowed &&+ !kbts__ContainsFeature(&Result->Features, FeatureId)) ||+ kbts__ContainsFeature(&FeatureStage->Features, FeatureId)))+ {+ BakedFeatureCount += 1;+ }+ }++ kbts_un BakedFeatureCapacity = KBTS__MIN(BakedFeatureCount, KBTS_MAX_SIMULTANEOUS_FEATURES);++ BakedFeatures = kbts__PointerPushArray(&MemoryAt, kbts__baked_feature, BakedFeatureCapacity);++ BakedFeatureCount = 0;++ KBTS__FOR(FeatureIndexIndex, 0, Langsys->FeatureIndexCount)+ {+ kbts_un FeatureIndex = FeatureIndices[FeatureIndexIndex];+ kbts__feature_pointer Feature = kbts__GetFeature(FeatureList, FeatureIndex);++ kbts_u32 FeatureId = kbts__FeatureTagToId(Feature.Tag);+ // We add all features indiscriminately for ops that might incorporate user features.+ if(Feature.Feature->LookupIndexCount &&+ // We add "all" features to user feature stages, except for features that are a default part of the shaper.+ // If a user asks for a default feature explicitly, it is unclear whether it should be applied now or in its+ // default stage.+ // Leaving the feature in its default stage seems like the better thing to do, because, supposedly, these features+ // will have been designed to apply at a specific point in the pipeline, and moving them makes little sense.+ ((UserFeaturesAllowed &&+ !kbts__ContainsFeature(&Result->Features, FeatureId)) ||+ kbts__ContainsFeature(&FeatureStage->Features, FeatureId)))+ {+ kbts__baked_feature BakedFeature = KBTS__ZERO;+ BakedFeature.FeatureTag = Feature.Tag;+ BakedFeature.FeatureId = FeatureId;+ // CAREFUL: We use SkipFlags as a temporary index until the end of the stage.+ BakedFeature.SkipFlags = kbts__SkipFlags(BakedFeature.FeatureId, Result->Shaper);+ BakedFeature.Count = Feature.Feature->LookupIndexCount;+ // These point directly into the file.+ BakedFeature.Indices = KBTS__POINTER_AFTER(kbts_u16, Feature.Feature);++ // @Incomplete+ //if(FeatureVariations)+ //{+ // KBTS__FOR(VariationIndex, 0, FeatureVariations->RecordCount)+ // {+ // kbts__feature_variation_pointer Variation = kbts__GetFeatureVariation(FeatureVariations, VariationIndex);+ // KBTS__FOR(ConditionIndex, 0, Variation.ConditionSet->Count)+ // {+ // kbts__condition_1 *Condition = kbts__GetCondition(Variation.ConditionSet, ConditionIndex);+ // KBTS_ASSERT(0);+ // }+ // }+ //}++ // For Myanmar, we could try and tag glyphs depending on their Indic properties in BeginCluster, just like we do for+ // Indic scripts.+ // However, Harfbuzz does _not_ do this, so it seems like a bunch of work that would, at best, make us diverge from+ // Harfbuzz more often.+ if((Result->Shaper != KBTS_SHAPER_MYANMAR) && (FeatureId >= 1) && (FeatureId <= 32))+ {+ // These must properly map KBTS__FEATURE_ID to kbts_glyph_flags!+ BakedFeature.GlyphFilter = (1 << (FeatureId - 1)) & KBTS__GLYPH_FEATURE_MASK;+ }++ if(Memory)+ {+ BakedFeatures[BakedFeatureCount] = BakedFeature;+ }++ BakedFeatureCount += 1;+ BakedFeatureLookupIndexCount += BakedFeature.Count;++ if(BakedFeatureCount >= BakedFeatureCapacity)+ {+ break;+ }+ }+ }++ kbts_u16 *OrderedFeatureIndices = kbts__PointerPushArray(&MemoryAt, kbts_u16, BakedFeatureLookupIndexCount);+ kbts_u16 *BakedFeatureLookupIndicesRead = kbts__PointerPushArray(&MemoryAt, kbts_u16, BakedFeatureCount);++ if(Memory)+ {+ kbts_un OrderedFeatureIndicesWritten = 0;++ KBTS__FOR(BakedFeatureIndex, 0, BakedFeatureCount)+ {+ BakedFeatureLookupIndicesRead[BakedFeatureIndex] = 0;+ }++ KBTS__FOR(OrderedLookupIndex, 0, BakedFeatureLookupIndexCount)+ {+ kbts_u16 LowestLookupIndex = 0xFFFF;+ kbts_un BestBakedFeatureIndex = 0;++ KBTS__FOR(BakedFeatureIndex, 0, BakedFeatureCount)+ {+ kbts__baked_feature *BakedFeature = &BakedFeatures[BakedFeatureIndex];+ kbts_un LookupIndicesRead = BakedFeatureLookupIndicesRead[BakedFeatureIndex];++ if(LookupIndicesRead < BakedFeature->Count)+ {+ kbts_u16 NextIndex = BakedFeature->Indices[LookupIndicesRead];++ if(NextIndex < LowestLookupIndex)+ {+ LowestLookupIndex = NextIndex;+ BestBakedFeatureIndex = BakedFeatureIndex;+ }+ }+ }++ BakedFeatureLookupIndicesRead[BestBakedFeatureIndex] += 1;+ OrderedFeatureIndices[OrderedFeatureIndicesWritten++] = (kbts_u16)BestBakedFeatureIndex;+ }++ KBTS_ASSERT(OrderedFeatureIndicesWritten == BakedFeatureLookupIndexCount);++ BakedStage->FeatureCount = (kbts_u16)BakedFeatureCount;+ BakedStage->FeatureIndexCount = (kbts_u16)BakedFeatureLookupIndexCount;+ BakedStage->Features = BakedFeatures;+ BakedStage->FeatureIndices = OrderedFeatureIndices;+ }+ }++ KBTS_ASSERT(FeatureStageIndex < Result->OpList.FeatureStageCount);+ FeatureStageIndex += 1;+ }+ }++ Result->FeatureStages = BakedStages;+ }+ }++ if(!Memory)+ {+ *Size = (kbts_un)(MemoryAt - (char *)Memory) + KBTS_ALIGNOF(kbts_shape_config);+ Result = 0;+ }++ return Result;+}++KBTS_EXPORT int kbts_SizeOfShapeConfig(kbts_font *Font, kbts_script Script, kbts_language Language)+{+ kbts_un Size;+ kbts__PlaceShapeConfig(Font, Script, Language, 0, &Size);++ return (int)Size;+}++KBTS_EXPORT kbts_shape_config *kbts_PlaceShapeConfig(kbts_font *Font, kbts_script Script, kbts_language Language, void *Memory)+{+ kbts_un Size;+ kbts_shape_config *Result = kbts__PlaceShapeConfig(Font, Script, Language, Memory, &Size);+ return Result;+}++KBTS_EXPORT kbts_shape_config *kbts_CreateShapeConfig(kbts_font *Font, kbts_script Script, kbts_language Language, kbts_allocator_function *Allocator, void *AllocatorData)+{+ if(!Allocator)+ {+ Allocator = kbts__DefaultAllocator;+ }++ kbts_un Size;+ kbts__PlaceShapeConfig(Font, Script, Language, 0, &Size);+ kbts_shape_config *Result = kbts__PlaceShapeConfig(Font, Script, Language, kbts__AllocatorAllocate(Allocator, AllocatorData, Size), &Size);+ if(Result)+ {+ Result->Allocator = Allocator;+ Result->AllocatorData = AllocatorData;+ }++ return Result;+}++KBTS_EXPORT void kbts_DestroyShapeConfig(kbts_shape_config *Config)+{+ if(Config->Allocator)+ {+ kbts__AllocatorFree(Config->Allocator, Config->AllocatorData, Config);+ }+}++KBTS_EXPORT int kbts_SizeOfShapeContext(void)+{+ int Result = sizeof(kbts_shape_context);+ return Result;+}++KBTS_EXPORT kbts_shape_context *kbts_PlaceShapeContext(kbts_allocator_function *Allocator, void *AllocatorData, void *Memory)+{+ kbts_shape_context *Result = (kbts_shape_context *)Memory;++ if(Memory)+ {+ if(!Allocator)+ {+ Allocator = kbts__DefaultAllocator;+ }++ KBTS_MEMSET(Result, 0, sizeof(*Result));++ Result->PermanentArena.Allocator = Allocator;+ Result->PermanentArena.AllocatorData = AllocatorData;++ Result->FontArena.Allocator = Allocator;+ Result->FontArena.AllocatorData = AllocatorData;++ Result->ConfigArena.Allocator = Allocator;+ Result->ConfigArena.AllocatorData = AllocatorData;++ Result->ScratchArena.Allocator = Allocator;+ Result->ScratchArena.AllocatorData = AllocatorData;++ Result->GlyphStorage.Arena.Allocator = Allocator;+ Result->GlyphStorage.Arena.AllocatorData = AllocatorData;++ KBTS__DLLIST_SENTINEL_INIT(&Result->FeatureOverrideSentinel);+ KBTS__DLLIST_SENTINEL_INIT(&Result->FreeFeatureOverrideSentinel);+ }++ return Result;+}++KBTS_EXPORT kbts_shape_context *kbts_PlaceShapeContextFixedMemory(void *Memory, int Size)+{+ kbts_shape_context *Result = 0;+ kbts_un SizeOfShapeContext = kbts_SizeOfShapeContext();+ kbts_un ContextAndArenaSize = sizeof(kbts_arena) + SizeOfShapeContext;++ if((Size >= 0) && ((kbts_un)Size >= ContextAndArenaSize))+ {+ kbts_arena *Arena = (kbts_arena *)KBTS__POINTER_OFFSET(kbts_arena, Memory, SizeOfShapeContext);+ kbts__InitializeFixedMemoryArena(Arena, KBTS__POINTER_AFTER(void, Arena), (kbts_un)Size - ContextAndArenaSize);++ Result = kbts_PlaceShapeContext(kbts__ArenaAllocator, Arena, Memory);+ }++ return Result;+}++KBTS_EXPORT kbts_shape_context *kbts_CreateShapeContext(kbts_allocator_function *Allocator, void *AllocatorData)+{+ if(!Allocator)+ {+ Allocator = kbts__DefaultAllocator;+ }++ kbts_shape_context *Result = kbts_PlaceShapeContext(Allocator, AllocatorData, kbts__AllocatorAllocate(Allocator, AllocatorData, (kbts_un)kbts_SizeOfShapeContext()));+ Result->SelfAllocator = Allocator;+ Result->SelfAllocatorData = AllocatorData;+ return Result;+}++KBTS_EXPORT void kbts_DestroyShapeContext(kbts_shape_context *Context)+{+ if(Context)+ {+ kbts__FreeArena(&Context->PermanentArena);+ kbts__FreeArena(&Context->ConfigArena);+ kbts__FreeArena(&Context->ScratchArena);+ kbts__FreeArena(&Context->FontArena);+ kbts__FreeArena(&Context->GlyphStorage.Arena);++ if(Context->SelfAllocator)+ {+ kbts__AllocatorFree(Context->SelfAllocator, Context->SelfAllocatorData, Context);+ }+ }+}++KBTS_EXPORT kbts_direction kbts_ScriptDirection(kbts_script Script)+{+ kbts_direction Result = ((Script == KBTS_SCRIPT_ARABIC) || (Script == KBTS_SCRIPT_HEBREW)) ? KBTS_DIRECTION_RTL : KBTS_DIRECTION_LTR;+ return Result;+}++static kbts__context_font *kbts__ShapePushFont(kbts_shape_context *Context)+{+ kbts__context_font *Result = 0;++ if(!Context->Error && (Context->FontCount < KBTS_CONTEXT_MAX_FONT_COUNT))+ {+ Result = &Context->Fonts[Context->FontCount++];+ Result->Font = 0;+ Result->Lifetime = kbts__BeginLifetime(&Context->FontArena);+ }++ return Result;+}++KBTS_EXPORT kbts_font *kbts_ShapePushFont(kbts_shape_context *Context, kbts_font *Font)+{+ if(!Context->Error)+ {+ kbts__context_font *ContextFont = kbts__ShapePushFont(Context);++ if(ContextFont)+ {+ ContextFont->Font = Font;+ }+ }++ return Font;+}++KBTS_EXPORT kbts_font *kbts_ShapePopFont(kbts_shape_context *Context)+{+ kbts_font *Result = 0;++ if(!Context->Error && Context->FontCount)+ {+ kbts__context_font *ContextFont = &Context->Fonts[Context->FontCount - 1];+ Result = ContextFont->Font;++ kbts__EndLifetime(&ContextFont->Lifetime);++ Context->FontCount -= 1;+ }++ return Result;+}++#ifndef KB_TEXT_SHAPE_NO_CRT+KBTS_EXPORT kbts_font *kbts_ShapePushFontFromFile(kbts_shape_context *Context, const char *FileName, int FontIndex)+{+ kbts__context_font *ContextFont = kbts__ShapePushFont(Context);+ kbts_font *Result = 0;++ if(!Context->Error)+ {+ Result = kbts__PushType(&Context->FontArena, kbts_font);+ if(Result)+ {+ *Result = kbts_FontFromFile(FileName, FontIndex, kbts__ArenaAllocator, &Context->FontArena, 0, 0);++ if(!Result->Error)+ {+ ContextFont->Font = Result;+ }+ else+ {+ kbts_ShapePopFont(Context);+ Result = 0;+ }+ }+ else+ {+ Context->Error = KBTS_SHAPE_ERROR_OUT_OF_MEMORY;+ }+ }++ return Result;+}+#endif++KBTS_EXPORT kbts_font *kbts_ShapePushFontFromMemory(kbts_shape_context *Context, void *Memory, int Length, int FontIndex)+{+ kbts_font *Result = 0;++ if(!Context->Error && (Length > 0))+ {+ kbts__context_font *ContextFont = kbts__ShapePushFont(Context);++ Result = kbts__PushType(&Context->FontArena, kbts_font);++ if(Result)+ {+ int ScratchSize, OutputSize;+ kbts_load_font_state State = KBTS__ZERO;+ kbts_load_font_error Error = kbts_LoadFont(Result, &State, Memory, Length, FontIndex, &ScratchSize, &OutputSize);+ if(Error == KBTS_LOAD_FONT_ERROR_NEED_TO_CREATE_BLOB)+ {+ void *Scratch = kbts__PushSize(&Context->ScratchArena, (kbts_un)ScratchSize, 8);+ void *Output = kbts__PushSize(&Context->FontArena, (kbts_un)OutputSize, 8);++ Error = kbts_PlaceBlob(Result, &State, Scratch, Output);+ }++ if(!Error)+ {+ ContextFont->Font = Result;+ }+ else+ {+ kbts_ShapePopFont(Context);+ Result = 0;+ }+ }+ }++ return Result;+}++static void kbts__EnsureGlyphStorageInitialized(kbts_glyph_storage *Storage)+{+ if(!Storage->GlyphSentinel.Next)+ {+ KBTS__DLLIST_SENTINEL_INIT(&Storage->GlyphSentinel);+ KBTS__DLLIST_SENTINEL_INIT(&Storage->FreeGlyphSentinel);+ }+}++KBTS_EXPORT int kbts_InitializeGlyphStorage(kbts_glyph_storage *Storage, kbts_allocator_function *Allocator, void *AllocatorData)+{+ int Result = 0;++ if(Storage)+ {+ Result = 1;+ KBTS_MEMSET(Storage, 0, sizeof(*Storage));++ Storage->Arena.Allocator = Allocator;+ Storage->Arena.AllocatorData = AllocatorData;+ }++ return Result;+}++KBTS_EXPORT int kbts_InitializeGlyphStorageFixedMemory(kbts_glyph_storage *Storage, void *Memory, int MemorySize)+{+ int Result = 0;++ if(Storage &&+ (MemorySize > 0))+ {+ KBTS_MEMSET(Storage, 0, sizeof(*Storage));++ Result = kbts__InitializeFixedMemoryArena(&Storage->Arena, Memory, (kbts_un)MemorySize);+ }++ return Result;+}++KBTS_EXPORT kbts_glyph_iterator kbts_ActiveGlyphIterator(kbts_glyph_storage *Storage)+{+ kbts_glyph_iterator Result = KBTS__ZERO;++ if(Storage && !Storage->Error)+ {+ kbts__EnsureGlyphStorageInitialized(Storage);++ Result.GlyphStorage = Storage;+ Result.CurrentGlyph = Storage->GlyphSentinel.Next;+ }++ return Result;+}++KBTS_EXPORT void kbts_ClearActiveGlyphs(kbts_glyph_storage *Storage)+{+ if(!Storage->Error)+ {+ kbts__EnsureGlyphStorageInitialized(Storage);++ kbts_glyph *First = Storage->GlyphSentinel.Next;+ kbts_glyph *Last = Storage->GlyphSentinel.Prev;++ if(kbts__GlyphIsValid(Storage, First))+ {+ // Free all previous glyphs.+ First->Prev = Storage->FreeGlyphSentinel.Prev;+ Last->Next = &Storage->FreeGlyphSentinel;+ First->Prev->Next = First;+ Last->Next->Prev = Last;+ }++ KBTS__DLLIST_SENTINEL_INIT(&Storage->GlyphSentinel);+ }+}++KBTS_EXPORT void kbts_FreeAllGlyphs(kbts_glyph_storage *Storage)+{+ kbts__FreeArena(&Storage->Arena);++ KBTS__DLLIST_SENTINEL_INIT(&Storage->GlyphSentinel);+ KBTS__DLLIST_SENTINEL_INIT(&Storage->FreeGlyphSentinel);+}++KBTS_EXPORT kbts_glyph *kbts_PushGlyph(kbts_glyph_storage *Storage, kbts_font *Font, int Codepoint, kbts_glyph_config *Config, int UserId)+{+ kbts_glyph *Result = 0;++ if(!Storage->Error)+ {+ kbts__EnsureGlyphStorageInitialized(Storage);++ kbts_glyph Template = KBTS__ZERO;+ if(Font)+ {+ Template = kbts_CodepointToGlyph(Font, Codepoint, Config, UserId);+ }+ else+ {+ Template.Codepoint = (kbts_u32)Codepoint;+ Template.Config = Config;+ // We do not want to use the template's UserId here, because it is just a bag of properties!+ // We want to keep the original UserId.+ }++ Result = kbts__InsertGlyphBefore(Storage, &Storage->GlyphSentinel, &Template);+ }++ return Result;+}++static int kbts__FeatureOverrideIsExtra(kbts_u32 Tag, int Value)+{+ int Result = 0;+ kbts__feature_id Id = kbts__FeatureTagToId(Tag);++ if(!Id || (kbts_u32)(Value > 1))+ {+ Result = 1;+ }++ return Result;+}++static void kbts__AddExtraFeatureOverride(kbts_glyph_config *Config, kbts__feature_override *Extra, kbts_u32 Tag, int Value)+{+ Extra->Tag = Tag;+ Extra->Value = Value;++ KBTS__DLLIST_INSERT_BEFORE(&Extra->Header, &Config->FeatureOverrideSentinel);+}++KBTS_EXPORT int kbts_SizeOfGlyphConfig(kbts_feature_override *Overrides, int OverrideCount)+{+ kbts_un StoredOverrideCount = 0;++ if(OverrideCount > 0)+ {+ KBTS__FOR(OverrideIndex, 0, (kbts_un)OverrideCount)+ {+ kbts_feature_override *Override = &Overrides[OverrideIndex];++ if(kbts__FeatureOverrideIsExtra(Override->Tag, Override->Value))+ {+ StoredOverrideCount += 1;+ }+ }+ }++ kbts_un Result = sizeof(kbts_glyph_config) + StoredOverrideCount * sizeof(kbts__feature_override);+ return (int)Result;+}++KBTS_EXPORT kbts_glyph_config *kbts_PlaceGlyphConfig(kbts_feature_override *Overrides, int OverrideCount, void *Memory)+{+ kbts_glyph_config *Result = (kbts_glyph_config *)Memory;+ if(Memory)+ {+ KBTS_MEMSET(Result, 0, sizeof(*Result));+ KBTS__DLLIST_SENTINEL_INIT(&Result->FeatureOverrideSentinel);++ kbts__feature_override *ExtraOverrides = KBTS__POINTER_AFTER(kbts__feature_override, Result);++ if(OverrideCount > 0)+ {+ KBTS__FOR(OverrideIndex, 0, (kbts_un)OverrideCount)+ {+ kbts_feature_override *Override = &Overrides[OverrideIndex];+ kbts__feature_id Id = kbts__FeatureTagToId(Override->Tag);++ if(kbts__FeatureOverrideIsExtra(Override->Tag, Override->Value))+ {+ kbts__feature_override *ExtraOverride = &ExtraOverrides[Result->ExtraOverrideCount++];++ kbts__AddExtraFeatureOverride(Result, ExtraOverride, Override->Tag, Override->Value);+ }++ kbts__AddFeature((Override->Value) ? &Result->EnabledFeatures : &Result->DisabledFeatures, Id);+ }++ if(Result->ExtraOverrideCount)+ {+ kbts__feature_override *Last = &ExtraOverrides[Result->ExtraOverrideCount - 1];+ Last->Header.Next = &Result->FeatureOverrideSentinel;+ Result->FeatureOverrideSentinel.Prev = &Last->Header;+ }+ }+ }++ return Result;+}++KBTS_EXPORT kbts_glyph_config *kbts_CreateGlyphConfig(kbts_feature_override *Overrides, int OverrideCount, kbts_allocator_function *Allocator, void *AllocatorData)+{+ if(!Allocator)+ {+ Allocator = kbts__DefaultAllocator;+ }++ kbts_glyph_config *Result = kbts_PlaceGlyphConfig(Overrides, OverrideCount, kbts__AllocatorAllocate(Allocator, AllocatorData, (kbts_un)kbts_SizeOfGlyphConfig(Overrides, OverrideCount)));++ if(Result)+ {+ Result->Allocator = Allocator;+ Result->AllocatorData = AllocatorData;+ }++ return Result;+}++KBTS_EXPORT void kbts_DestroyGlyphConfig(kbts_glyph_config *Config)+{+ if(Config && Config->Allocator)+ {+ kbts__AllocatorFree(Config->Allocator, Config->AllocatorData, Config);+ }+}++KBTS_EXPORT kbts_shape_error kbts_ShapeError(kbts_shape_context *Context)+{+ kbts_shape_error Result = Context->Error;+ return Result;+}++KBTS_EXPORT void kbts_ShapeBegin(kbts_shape_context *Context, kbts_direction ParagraphDirection, kbts_language Language)+{+ if(!Context->Error)+ {+ kbts__ClearArena(&Context->ScratchArena);+ kbts_ClearActiveGlyphs(&Context->GlyphStorage);++ Context->BreakStartIndex = 0;+ Context->CurrentGlyphConfig = 0;+ Context->NeedNewGlyphConfig = 1;++ Context->ParagraphDirection = ParagraphDirection;+ Context->Language = Language;+ Context->UserFeatures = KBTS__ZERO_TYPE(kbts__feature_set);++ Context->InputCodepointCount = 0;+ Context->NextUserId = 0;+ Context->LastGraphemeBreak = 0;+ Context->LastLineBreakIndex = 0;+ Context->RunFont = 0;+ Context->RunScript = 0;+ Context->RunDirection = 0;+ Context->ExistingShapeConfigCount = 0;++ kbts_BreakBegin(&Context->BreakState, ParagraphDirection, KBTS_JAPANESE_LINE_BREAK_STYLE_NORMAL, 0);+ }+}++typedef struct kbts__input_codepoint_index+{+ kbts_u32 BlockIndex;+ kbts_u32 CodepointIndex;+ kbts_u32 BlockCodepointCount;+} kbts__input_codepoint_index;++static kbts__input_codepoint_index kbts__InputCodepointIndex(kbts_un FlatCodepointIndex)+{+ kbts__input_codepoint_index Result = KBTS__ZERO;++ kbts_un MsbPosition = kbts__MsbPositionOrZero32((kbts_u32)FlatCodepointIndex);+ if(MsbPosition <= KBTS__INPUT_CODEPOINT_FIRST_BLOCK_MSB)+ {+ Result.BlockIndex = 0;+ Result.CodepointIndex = (kbts_u32)FlatCodepointIndex;+ Result.BlockCodepointCount = 1 << (KBTS__INPUT_CODEPOINT_FIRST_BLOCK_MSB + 1);+ }+ else+ {+ Result.BlockIndex = (kbts_u32)(MsbPosition - KBTS__INPUT_CODEPOINT_FIRST_BLOCK_MSB);+ Result.CodepointIndex = (kbts_u32)(FlatCodepointIndex & ~(1 << MsbPosition));+ Result.BlockCodepointCount = (kbts_u32)(1 << MsbPosition);+ }++ return Result;+}++static kbts_shape_codepoint *kbts__InputCodepoint(kbts_shape_context *Context, kbts_un Index)+{+ kbts_shape_codepoint *Result = 0;++ if(!Context->Error)+ {+ kbts__input_codepoint_index InputIndex = kbts__InputCodepointIndex(Index);++ kbts_shape_codepoint *Block = Context->InputBlocks[InputIndex.BlockIndex];+ if(!Block)+ {+ Block = kbts__PushArray(&Context->PermanentArena, kbts_shape_codepoint, InputIndex.BlockCodepointCount);+ if(!Block)+ {+ Context->Error = KBTS_SHAPE_ERROR_OUT_OF_MEMORY;+ return Result;+ }++ Context->InputBlocks[InputIndex.BlockIndex] = Block;+ }++ Result = &Context->InputBlocks[InputIndex.BlockIndex][InputIndex.CodepointIndex];+ }++ return Result;+}++static kbts_shape_codepoint_iterator kbts__InputCodepointIterator(kbts_shape_context *Context, kbts_un StartCodepointIndex, kbts_un OnePastLastCodepointIndex)+{+ kbts_shape_codepoint_iterator Result = KBTS__ZERO;++ if(Context &&+ !Context->Error &&+ (OnePastLastCodepointIndex > StartCodepointIndex))+ {+ kbts__input_codepoint_index StartInputIndex = kbts__InputCodepointIndex(StartCodepointIndex);+ kbts__input_codepoint_index OnePastLastInputIndex = kbts__InputCodepointIndex(OnePastLastCodepointIndex);++ Result.Context = Context;+ Result.BlockIndex = StartInputIndex.BlockIndex;+ Result.CodepointIndex = StartInputIndex.CodepointIndex;+ Result.EndBlockIndex = OnePastLastInputIndex.BlockIndex;+ Result.OnePastLastCodepointIndex = OnePastLastInputIndex.CodepointIndex;+ Result.CurrentBlockCodepointCount = (Result.BlockIndex == Result.EndBlockIndex) ? Result.OnePastLastCodepointIndex : StartInputIndex.BlockCodepointCount;+ Result.FlatCodepointIndex = (kbts_u32)StartCodepointIndex;+ }++ return Result;+}++KBTS_EXPORT kbts_shape_codepoint_iterator kbts_ShapeCurrentCodepointsIterator(kbts_shape_context *Context)+{+ kbts_shape_codepoint_iterator Result = kbts__InputCodepointIterator(Context, 0, Context->InputCodepointCount);++ return Result;+}++static int kbts__NextInputCodepoint(kbts_shape_codepoint_iterator *It, int *CodepointIndex)+{+ int Result = 0;++ if(It->CodepointIndex >= It->CurrentBlockCodepointCount)+ {+ It->BlockIndex += 1;+ It->CodepointIndex = 0;+ It->CurrentBlockCodepointCount = (It->BlockIndex == It->EndBlockIndex) ? It->OnePastLastCodepointIndex : (1 << (It->BlockIndex + KBTS__INPUT_CODEPOINT_FIRST_BLOCK_MSB));+ }++ if(It->BlockIndex <= It->EndBlockIndex)+ {+ if(CodepointIndex)+ {+ *CodepointIndex = (int)It->FlatCodepointIndex;+ }++ It->Codepoint = &It->Context->InputBlocks[It->BlockIndex][It->CodepointIndex++];+ It->FlatCodepointIndex += 1;++ Result = 1;+ }++ return Result;+}++KBTS_EXPORT int kbts_ShapeCodepointIteratorIsValid(kbts_shape_codepoint_iterator *It)+{+ int Result = It->Context && (It->BlockIndex <= It->EndBlockIndex);+ return Result;+}++KBTS_EXPORT int kbts_ShapeCodepointIteratorNext(kbts_shape_codepoint_iterator *It, kbts_shape_codepoint *Codepoint, int *CodepointIndex)+{+ int Result = kbts__NextInputCodepoint(It, CodepointIndex);++ if(Result)+ {+ *Codepoint = *It->Codepoint;+ }++ return Result;+}++KBTS_EXPORT int kbts_ShapeGetShapeCodepoint(kbts_shape_context *Context, int CodepointIndex, kbts_shape_codepoint *Codepoint)+{+ int Result = 0;++ if((CodepointIndex >= 0) &&+ ((kbts_un)CodepointIndex < Context->InputCodepointCount))+ {+ kbts_shape_codepoint *Source = kbts__InputCodepoint(Context, (kbts_un)CodepointIndex);+ *Codepoint = *Source;++ Result = 1;+ }++ return Result;+}++static void kbts__UpdateBreaks(kbts_shape_context *Context)+{+ if(!(Context->Flags & KBTS__CONTEXT_FLAG_MANUAL_SEGMENTATION))+ {+ kbts_break Break;+ while(kbts_Break(&Context->BreakState, &Break))+ {+ // Strictly speaking, we do not need all of the flags, but we record them all anyway so we can expose them to the user.+ kbts_un BreakPosition = (kbts_u32)Break.Position + Context->BreakStartIndex;+ kbts_shape_codepoint *InputCodepoint = kbts__InputCodepoint(Context, BreakPosition);++ if(Break.Flags & KBTS_BREAK_FLAG_LINE_HARD)+ {+ Context->LastLineBreakIndex = (kbts_u32)BreakPosition;+ }++ if(Break.Flags & KBTS_BREAK_FLAG_GRAPHEME)+ {+ // Try fonts, potentially break run.+ kbts_font *MatchFont = 0;++ for(kbts_un FontIndex = Context->FontCount;+ FontIndex;+ --FontIndex)+ {+ kbts_font *Font = Context->Fonts[FontIndex - 1].Font;+ kbts_font_coverage_test CoverageTest;+ kbts_FontCoverageTestBegin(&CoverageTest, Font);++ kbts_shape_codepoint_iterator It = kbts__InputCodepointIterator(Context, Context->LastGraphemeBreakIndex, BreakPosition);++ while(kbts__NextInputCodepoint(&It, 0))+ {+ kbts_shape_codepoint *GraphemeCodepoint = It.Codepoint;++ kbts_FontCoverageTestCodepoint(&CoverageTest, GraphemeCodepoint->Codepoint);+ }++ kbts_FontCoverageTestEnd(&CoverageTest);++ if(!CoverageTest.Error)+ {+ MatchFont = Font;++ break;+ }+ }++ Context->LastGraphemeBreak->Font = MatchFont;+ Context->LastGraphemeBreak = InputCodepoint;+ Context->LastGraphemeBreakIndex = (kbts_u32)BreakPosition;+ }++ InputCodepoint->BreakFlags |= Break.Flags;+ if(Break.Flags & KBTS_BREAK_FLAG_SCRIPT)+ {+ InputCodepoint->Script = Break.Script;+ }+ if(Break.Flags & KBTS_BREAK_FLAG_DIRECTION)+ {+ InputCodepoint->Direction = Break.Direction;+ }+ if(Break.Flags & KBTS_BREAK_FLAG_PARAGRAPH_DIRECTION)+ {+ InputCodepoint->ParagraphDirection = Break.ParagraphDirection;+ }+ }+ }+}++KBTS_EXPORT void kbts_ShapeBeginManualRuns(kbts_shape_context *Context)+{+ if(!Context->Error)+ {+ if(Context->InputCodepointCount > 0)+ {+ kbts_BreakEnd(&Context->BreakState);+ kbts__UpdateBreaks(Context);+ }++ Context->Flags |= KBTS__CONTEXT_FLAG_MANUAL_SEGMENTATION;+ }+}++KBTS_EXPORT void kbts_ShapeNextManualRun(kbts_shape_context *Context, kbts_direction Direction, kbts_script Script)+{+ if(!Context->Error &&+ (Context->Flags & KBTS__CONTEXT_FLAG_MANUAL_SEGMENTATION))+ {+ Context->Flags |= KBTS__CONTEXT_FLAG_START_OF_MANUAL_RUN | KBTS__CONTEXT_FLAG_USE_MANUAL_BREAK_INFO;++ Context->ManualRunDirection = Direction;+ Context->ManualRunScript = Script;+ }+}++KBTS_EXPORT void kbts_ShapeEndManualRuns(kbts_shape_context *Context)+{+ if(!Context->Error &&+ (Context->Flags & KBTS__CONTEXT_FLAG_MANUAL_SEGMENTATION))+ {+ Context->Flags &= ~KBTS__CONTEXT_FLAG_MANUAL_SEGMENTATION;++ if(Context->InputCodepointCount > 0)+ {+ kbts_BreakBegin(&Context->BreakState, Context->ParagraphDirection, KBTS_JAPANESE_LINE_BREAK_STYLE_NORMAL, 0);+ Context->BreakStartIndex = (kbts_u32)Context->InputCodepointCount;+ }+ }+}++KBTS_EXPORT void kbts_ShapeManualBreak(kbts_shape_context *Context)+{+ kbts_ShapeBeginManualRuns(Context);+ Context->Flags |= KBTS__CONTEXT_FLAG_START_OF_MANUAL_RUN;+ kbts_ShapeEndManualRuns(Context);+}++KBTS_EXPORT void kbts_ShapeCodepointWithUserId(kbts_shape_context *Context, int Codepoint, int UserId)+{+ if(!Context->Error)+ {+ if(Context->NeedNewGlyphConfig)+ {+ kbts_glyph_config *Config = kbts__PushType(&Context->ScratchArena, kbts_glyph_config);+ if(!Config)+ {+ Context->Error = KBTS_SHAPE_ERROR_OUT_OF_MEMORY;+ return;+ }++ *Config = KBTS__ZERO_TYPE(kbts_glyph_config);+ KBTS__DLLIST_SENTINEL_INIT(&Config->FeatureOverrideSentinel);++ kbts__feature_set Features = KBTS__ZERO;+ for(kbts__feature_override_header *OverrideHeader = Context->FeatureOverrideSentinel.Prev;+ OverrideHeader != &Context->FeatureOverrideSentinel;+ OverrideHeader = OverrideHeader->Prev)+ {+ kbts__feature_override *Override = (kbts__feature_override *)OverrideHeader;+ kbts__feature_id Id = kbts__FeatureTagToId(Override->Tag);++ if(!Id || !kbts__ContainsFeature(&Features, Id))+ {+ if(kbts__FeatureOverrideIsExtra(Override->Tag, Override->Value))+ {+ kbts__feature_override *Insert = kbts__PushType(&Context->ScratchArena, kbts__feature_override);+ if(!Insert)+ {+ Context->Error = KBTS_SHAPE_ERROR_OUT_OF_MEMORY;+ return;+ }++ kbts__AddExtraFeatureOverride(Config, Insert, Override->Tag, Override->Value);+ }++ kbts__AddFeature(&Features, Id);+ kbts__AddFeature((Override->Value) ? &Config->EnabledFeatures : &Config->DisabledFeatures, Id);+ }+ }++ Context->CurrentGlyphConfig = Config;+ Context->NeedNewGlyphConfig = 0;+ }++ { // Add the codepoint.+ kbts_un FlatCodepointIndex = Context->InputCodepointCount;+ kbts_shape_codepoint InputCodepoint = KBTS__ZERO;+ InputCodepoint.Codepoint = Codepoint;+ InputCodepoint.UserId = UserId;+ InputCodepoint.Config = Context->CurrentGlyphConfig;++ // @Robustness: There is probably a saner way of doing this.+ // When we do a manual break, we may have line breaks go out-of-bounds, and we+ // do not want to lose that information.+ if(FlatCodepointIndex &&+ (FlatCodepointIndex == Context->LastLineBreakIndex))+ {+ InputCodepoint.BreakFlags |= KBTS_BREAK_FLAG_LINE;+ }++ if(Context->Flags & KBTS__CONTEXT_FLAG_START_OF_MANUAL_RUN)+ {+ InputCodepoint.BreakFlags |= KBTS_BREAK_FLAG_MANUAL;++ if(Context->Flags & KBTS__CONTEXT_FLAG_USE_MANUAL_BREAK_INFO)+ {+ InputCodepoint.Direction = Context->ManualRunDirection;+ InputCodepoint.Script = Context->ManualRunScript;+ }++ Context->Flags &= ~KBTS__CONTEXT_FLAG_START_OF_MANUAL_RUN;+ }++ kbts_shape_codepoint *To = kbts__InputCodepoint(Context, FlatCodepointIndex);+ if(To)+ {+ *To = InputCodepoint;+ }++ if(!Context->LastGraphemeBreak)+ {+ Context->LastGraphemeBreak = To;+ }++ Context->InputCodepointCount += 1;+ }++ if(!(Context->Flags & KBTS__CONTEXT_FLAG_MANUAL_SEGMENTATION))+ {+ // Check for breaks.+ kbts_BreakAddCodepoint(&Context->BreakState, Codepoint, 1, 0);++ kbts__UpdateBreaks(Context);+ }+ }+}+static void kbts__ShapeCodepoint(kbts_shape_context *Context, int Codepoint, int UserIdIncrement)+{+ int UserId = Context->NextUserId;+ Context->NextUserId += UserIdIncrement;+ kbts_ShapeCodepointWithUserId(Context, Codepoint, UserId);+}+KBTS_EXPORT void kbts_ShapeCodepoint(kbts_shape_context *Context, int Codepoint)+{+ if(!Context->Error)+ {+ kbts__ShapeCodepoint(Context, Codepoint, 1);+ }+}++KBTS_EXPORT void kbts_ShapeUtf32WithUserId(kbts_shape_context *Context, int *Utf32, int Length, int BaseUserId, int UserIdIncrement)+{+ if(!Context->Error && (Length > 0))+ {+ int UserId = BaseUserId;++ KBTS__FOR(Utf32Index, 0, (kbts_un)Length)+ {+ int Codepoint = Utf32[Utf32Index];+ kbts_ShapeCodepointWithUserId(Context, Codepoint, UserId);++ UserId += UserIdIncrement;+ }+ }+}+KBTS_EXPORT void kbts_ShapeUtf32(kbts_shape_context *Context, int *Utf32, int Length)+{+ if(!Context->Error && (Length > 0))+ {+ KBTS__FOR(Utf32Index, 0, (kbts_un)Length)+ {+ int Codepoint = Utf32[Utf32Index];+ kbts_ShapeCodepoint(Context, Codepoint);+ }+ }+}++KBTS_EXPORT void kbts_ShapeUtf8WithUserId(kbts_shape_context *Context, const char *Utf8, int Length, int BaseUserId, kbts_user_id_generation_mode UserIdGenerationMode)+{+ if(!Context->Error && (Length > 0))+ {+ const char *At = Utf8;+ const char *End = Utf8 + Length;+ int UserId = BaseUserId;++ int CodepointIncrement = (UserIdGenerationMode == KBTS_USER_ID_GENERATION_MODE_CODEPOINT_INDEX) ? 1 : 0;+ int SourceCharacterMask = (UserIdGenerationMode == KBTS_USER_ID_GENERATION_MODE_SOURCE_INDEX) ? ~0 : 0;++ while(At < End)+ {+ kbts_decode Decode = kbts_DecodeUtf8(At, (kbts_un)(End - At));++ if(Decode.Valid)+ {+ kbts_ShapeCodepointWithUserId(Context, Decode.Codepoint, UserId);++ UserId += CodepointIncrement;+ }++ At += Decode.SourceCharactersConsumed;+ UserId += Decode.SourceCharactersConsumed & SourceCharacterMask;+ }+ }+}+KBTS_EXPORT void kbts_ShapeUtf8(kbts_shape_context *Context, const char *Utf8, int Length, kbts_user_id_generation_mode UserIdGenerationMode)+{+ if(!Context->Error && (Length > 0))+ {+ const char *At = Utf8;+ const char *End = Utf8 + Length;+ while(At < End)+ {+ kbts_decode Decode = kbts_DecodeUtf8(At, (kbts_un)(End - At));++ if(Decode.Valid)+ {+ int Increment = 0;+ if(UserIdGenerationMode == KBTS_USER_ID_GENERATION_MODE_CODEPOINT_INDEX)+ {+ Increment = 1;+ }+ else if(UserIdGenerationMode == KBTS_USER_ID_GENERATION_MODE_SOURCE_INDEX)+ {+ Increment = Decode.SourceCharactersConsumed;+ }++ kbts__ShapeCodepoint(Context, Decode.Codepoint, Increment);+ }++ At += Decode.SourceCharactersConsumed;+ }+ }+}++KBTS_EXPORT void kbts_ShapePushFeature(kbts_shape_context *Context, kbts_u32 Tag, int Value)+{+ if(!Context->Error)+ {+ kbts__feature_override *Override;+ kbts__feature_override_header *Header = Context->FreeFeatureOverrideSentinel.Prev;+ if(Header != &Context->FreeFeatureOverrideSentinel)+ {+ Override = (kbts__feature_override *)Header;+ }+ else+ {+ Override = kbts__PushType(&Context->PermanentArena, kbts__feature_override);+ }++ KBTS__DLLIST_INSERT_BEFORE(&Override->Header, &Context->FeatureOverrideSentinel);+ Override->Tag = Tag;+ Override->Value = Value;++ kbts__feature_id Id = kbts__FeatureTagToId(Tag);+ kbts__AddFeature(&Context->UserFeaturesEnabled, Id);++ Context->NeedNewGlyphConfig = 1;+ }+}++KBTS_EXPORT int kbts_ShapePopFeature(kbts_shape_context *Context, kbts_u32 Tag)+{+ int Result = 0;++ if(!Context->Error)+ {+ for(kbts__feature_override_header *Header = Context->FeatureOverrideSentinel.Prev;+ Header != &Context->FeatureOverrideSentinel;+ Header = Header->Prev)+ {+ kbts__feature_override *Override = (kbts__feature_override *)Header;++ if(Override->Tag == Tag)+ {+ Result = 1;++ KBTS__DLLIST_REMOVE(Header);+ KBTS__DLLIST_INSERT_BEFORE(Header, &Context->FreeFeatureOverrideSentinel);++ break;+ }+ }++ if(Result)+ {+ Context->NeedNewGlyphConfig = 1;+ }+ }++ return Result;+}++static void kbts__ShapeDirect(kbts__shape_scratchpad *Scratchpad, kbts_shape_config *Config, kbts_glyph_storage *Storage)+{+ KBTS_INSTRUMENT_BLOCK_BEGIN(ReadOpLoop0);+ kbts__arena_lifetime Lifetime = kbts__BeginLifetime(Scratchpad->Arena);++ if(kbts__GlyphIsValid(Storage, Storage->GlyphSentinel.Next))+ {+ // For simple shapers, all of the shaping happens in this single loop.+ // For complex shapers, this loop is preparing the text for clustering logic, which happens below.+ while(kbts__ReadOp(Scratchpad, Config, KBTS__OP_KIND_BEGIN_CLUSTER))+ {+ kbts__ExecuteOp(Scratchpad, Config, Storage);++ if(Scratchpad->Error)+ {+ goto Done;+ }+ }++ KBTS_INSTRUMENT_BLOCK_END(ReadOpLoop0);++ if(Scratchpad->OpKind == KBTS__OP_KIND_BEGIN_CLUSTER)+ {+ kbts_u32 BeginClusterIp = Scratchpad->Ip;+ kbts_u32 BeginClusterFeatureStagesRead = Scratchpad->FeatureStagesRead;+ kbts_glyph *TopLevelGlyph = Storage->GlyphSentinel.Next;++ Scratchpad->ClusterAtStartOfWord = 1;++ while(kbts__GlyphIsValid(Storage, TopLevelGlyph))+ {+ int WordBreak = 0;++ Scratchpad->Ip = BeginClusterIp;+ Scratchpad->FeatureStagesRead = BeginClusterFeatureStagesRead;++ {+ // We need to store this in case TopLevelGlyph is reordered.+ kbts_glyph *OneBeforeFirstClusterGlyph = TopLevelGlyph->Prev;+ kbts_glyph *OnePastLastClusterGlyph = kbts__BeginCluster(Scratchpad, Config, Storage, TopLevelGlyph);++ if(Scratchpad->Error)+ {+ goto Done;+ }++ WordBreak = !(OnePastLastClusterGlyph->Prev->UnicodeFlags & KBTS_UNICODE_FLAG_PART_OF_WORD);+ Scratchpad->Cluster = kbts__PushGlyphList(Storage, OneBeforeFirstClusterGlyph->Next, OnePastLastClusterGlyph->Prev);+ }++ while(kbts__ReadOp(Scratchpad, Config, KBTS__OP_KIND_END_CLUSTER))+ {+ kbts__ExecuteOp(Scratchpad, Config, Storage);++ if(Scratchpad->Error)+ {+ goto Done;+ }+ }++ kbts__EndCluster(Scratchpad, Config, Storage);++ while(kbts__ReadOp(Scratchpad, Config, KBTS__OP_KIND_END_SYLLABLE))+ {+ kbts__ExecuteOp(Scratchpad, Config, Storage);++ if(Scratchpad->Error)+ {+ goto Done;+ }+ }++ // Reattach the cluster to the main list.+ Storage->GlyphSentinel.Next->Prev = Scratchpad->Cluster.OneBeforeFirst;+ Storage->GlyphSentinel.Prev->Next = Scratchpad->Cluster.OnePastLast;+ TopLevelGlyph = Scratchpad->Cluster.OnePastLast;++ kbts__PopGlyphList(Storage, &Scratchpad->Cluster);++ Scratchpad->ClusterAtStartOfWord = WordBreak;+ }++ // Post-clustering ops work across clusters.+ // This is where Indic GPOS + post-passes happen.+ while(kbts__ReadOp(Scratchpad, Config, 0))+ {+ kbts__ExecuteOp(Scratchpad, Config, Storage);++ if(Scratchpad->Error)+ {+ goto Done;+ }+ }+ }+ }++ Done:;+ kbts__EndLifetime(&Lifetime);+ return;+}++KBTS_EXPORT kbts_shape_error kbts_ShapeDirect(kbts_shape_config *Config, kbts_glyph_storage *Storage, kbts_direction RunDirection, kbts_allocator_function *Allocator, void *AllocatorData, kbts_glyph_iterator *Output)+{+ if(!Allocator)+ {+ Allocator = kbts__DefaultAllocator;+ }++ kbts_arena Arena = KBTS__ZERO;+ Arena.Allocator = Allocator;+ Arena.AllocatorData = AllocatorData;++ kbts__shape_scratchpad *Scratchpad = kbts__PushType(&Arena, kbts__shape_scratchpad);+ KBTS_MEMSET(Scratchpad, 0, sizeof(*Scratchpad));+ Scratchpad->Arena = &Arena;+ Scratchpad->RunDirection = RunDirection;++ kbts__ShapeDirect(Scratchpad, Config, Storage);+ kbts_shape_error Result = Scratchpad->Error;++ if(!Result)+ {+ *Output = kbts_ActiveGlyphIterator(Storage);+ }+ else+ {+ *Output = KBTS__ZERO_TYPE(kbts_glyph_iterator);+ }++ kbts__FreeArena(&Arena);++ return Result;+}++KBTS_EXPORT kbts_shape_error kbts_ShapeDirectFixedMemory(kbts_shape_config *Config, kbts_glyph_storage *Storage, kbts_direction RunDirection, void *Memory, int MemorySize, kbts_glyph_iterator *Output)+{+ kbts_shape_error Result = 0;++ if(Config && Storage && !Storage->Error && Memory && (MemorySize > 0))+ {+ kbts_arena Arena;++ if(kbts__InitializeFixedMemoryArena(&Arena, Memory, (kbts_un)MemorySize))+ {+ Result = kbts_ShapeDirect(Config, Storage, RunDirection, kbts__ArenaAllocator, &Arena, Output);+ }+ }++ return Result;+}++static void kbts__BeginParagraph(kbts_shape_context *Context)+{+ Context->RunFont = 0;+ if(Context->FontCount)+ {+ Context->RunFont = Context->Fonts[Context->FontCount - 1].Font;+ }++ Context->RunScript = 0;+ Context->RunParagraphDirection = 0;+ Context->RunDirection = 0;+}++KBTS_EXPORT void kbts_ShapeEnd(kbts_shape_context *Context)+{+ if(!Context->Error)+ {+ // We check the break flags of the one-past-last codepoint, so reset it here.+ kbts_shape_codepoint *OnePastLastCodepoint = kbts__InputCodepoint(Context, Context->InputCodepointCount);+ *OnePastLastCodepoint = KBTS__ZERO_TYPE(kbts_shape_codepoint);++ kbts_BreakEnd(&Context->BreakState);+ kbts__UpdateBreaks(Context);++ Context->RunCodepointIterator.Context = 0;+ Context->DoneShapingRuns = 0;++ kbts__BeginParagraph(Context);+ }+}++KBTS_EXPORT int kbts_ShapeRun(kbts_shape_context *Context, kbts_run *Run)+{+ int Result = 0;++ if(!Context->Error &&+ !Context->DoneShapingRuns)+ {+ kbts_font *RunFont = Context->RunFont;+ kbts_script RunScript = Context->RunScript;+ kbts_direction RunParagraphDirection = Context->RunParagraphDirection;+ kbts_direction RunDirection = Context->RunDirection;+ kbts_language Language = Context->Language;++ Run->Flags = 0;++ kbts_ClearActiveGlyphs(&Context->GlyphStorage);++ int Initialized = 1;++ if(!Context->RunCodepointIterator.Context)+ {+ Context->RunCodepointIterator = kbts__InputCodepointIterator(Context, 0, Context->InputCodepointCount);+ Initialized = 0;+ }++ kbts_shape_codepoint_iterator *It = &Context->RunCodepointIterator;++ if(kbts_ShapeCodepointIteratorIsValid(It))+ {+ int InputCodepointIndex = 0;+ while(kbts__NextInputCodepoint(It, &InputCodepointIndex))+ {+ kbts_shape_codepoint *InputCodepoint = It->Codepoint;++ // Resolve neutral directions.+ if((InputCodepoint->BreakFlags & KBTS_BREAK_FLAG_DIRECTION) &&+ (InputCodepoint->Direction == KBTS_DIRECTION_DONT_KNOW))+ {+ InputCodepoint->Direction = RunParagraphDirection;+ }++ int First = !Result;+ Result = 1;++ kbts_font *CodepointFont = InputCodepoint->Font;+ kbts_script CodepointScript = InputCodepoint->Script;+ kbts_direction CodepointDirection = InputCodepoint->Direction;+ kbts_direction CodepointParagraphDirection = InputCodepoint->ParagraphDirection;+ kbts_break_flags CodepointBreakFlags = InputCodepoint->BreakFlags;++ int NewLine = !First && (CodepointBreakFlags & (KBTS_BREAK_FLAG_LINE_HARD | KBTS_BREAK_FLAG_MANUAL));++ if(First)+ {+ Run->Flags = CodepointBreakFlags;++ if(CodepointBreakFlags & KBTS_BREAK_FLAG_LINE_HARD)+ {+ kbts__BeginParagraph(Context);+ RunFont = Context->RunFont;+ RunScript = 0;+ RunDirection = 0;++ // If we see a bunch of whitespace at the beginning of a paragraph,+ // we want to merge with the first actual text that shows up.+ Initialized = 0;+ }+ }++ if((CodepointFont && (CodepointFont != RunFont)) ||+ (CodepointScript && (CodepointScript != RunScript)) ||+ (CodepointDirection && (CodepointDirection != RunDirection)) ||+ (CodepointParagraphDirection && (CodepointParagraphDirection != RunParagraphDirection)) ||+ NewLine)+ {+ if(CodepointFont)+ {+ Context->RunFont = CodepointFont;+ }+ if(CodepointScript)+ {+ Context->RunScript = CodepointScript;+ }+ if(CodepointDirection)+ {+ Context->RunDirection = CodepointDirection;+ }+ if(CodepointParagraphDirection)+ {+ Context->RunParagraphDirection = CodepointParagraphDirection;+ }++ if(Initialized || NewLine)+ {+ // Rewind the current codepoint.+ // We could also try to peek the codepoint before advancing, but this seems fine.+ if(!It->CodepointIndex)+ {+ It->BlockIndex -= 1;+ It->CodepointIndex = (1 << (It->BlockIndex + KBTS__INPUT_CODEPOINT_FIRST_BLOCK_MSB)) - 1;+ }+ else+ {+ It->CodepointIndex -= 1;+ }++ It->FlatCodepointIndex -= 1;++ goto FoundBreak;+ }+ else+ {+ // Initialize and keep matching.+ RunFont = Context->RunFont;+ RunScript = Context->RunScript;+ RunDirection = Context->RunDirection;+ RunParagraphDirection = Context->RunParagraphDirection;++ kbts_PushGlyph(&Context->GlyphStorage, RunFont, InputCodepoint->Codepoint, InputCodepoint->Config, InputCodepointIndex);++ Initialized = 1;+ }+ }+ else+ {+ kbts_PushGlyph(&Context->GlyphStorage, RunFont, InputCodepoint->Codepoint, InputCodepoint->Config, InputCodepointIndex);+ }+ }++ FoundBreak:;++ if(Result)+ {+ kbts_shape_config *Config = 0;+ KBTS__FOR(ExistingConfigIndex, 0, Context->ExistingShapeConfigCount)+ {+ kbts__existing_shape_config *Existing = &Context->ExistingShapeConfigs[ExistingConfigIndex];++ if((Existing->Font == RunFont) &&+ (Existing->Script == RunScript))+ {+ Config = Existing->Config;++ break;+ }+ }++ if(!Config)+ {+ Config = kbts_CreateShapeConfig(RunFont, RunScript, Language, kbts__ArenaAllocator, &Context->ScratchArena);++ if(Context->ExistingShapeConfigCount < KBTS__ARRAY_LENGTH(Context->ExistingShapeConfigs))+ {+ kbts__existing_shape_config *NewExisting = &Context->ExistingShapeConfigs[Context->ExistingShapeConfigCount++];++ NewExisting->Config = Config;+ NewExisting->Font = RunFont;+ NewExisting->Script = RunScript;+ }+ }++ if(!RunDirection)+ {+ RunDirection = KBTS_DIRECTION_LTR;++ if((Config->Shaper == KBTS_SHAPER_ARABIC) ||+ (Config->Shaper == KBTS_SHAPER_HEBREW))+ {+ RunDirection = KBTS_DIRECTION_RTL;+ }+ }++ kbts__shape_scratchpad *Scratchpad = kbts__PushType(&Context->ScratchArena, kbts__shape_scratchpad);+ KBTS_MEMSET(Scratchpad, 0, sizeof(*Scratchpad));+ Scratchpad->Arena = &Context->ScratchArena;+ Scratchpad->RunDirection = RunDirection;++ kbts__ShapeDirect(Scratchpad, Config, &Context->GlyphStorage);++ if(Scratchpad->Error)+ {+ Context->Error = Scratchpad->Error;+ }+ }+ }+ else+ {+ kbts_shape_codepoint *OnePastLast = kbts__InputCodepoint(Context, Context->InputCodepointCount);++ if(OnePastLast->BreakFlags & KBTS_BREAK_FLAG_LINE_HARD)+ {+ // Signal the terminating line break with a 0-sized run.+ Run->Flags = OnePastLast->BreakFlags;++ Result = 1;+ }++ Context->DoneShapingRuns = 1;+ }++ if(Result)+ {+ Run->Font = RunFont;+ Run->Script = RunScript;+ Run->ParagraphDirection = RunParagraphDirection;+ Run->Direction = RunDirection;+ Run->Glyphs = kbts_ActiveGlyphIterator(&Context->GlyphStorage);+ }+ }++ return Result;+}++KBTS_EXPORT int kbts_GlyphIteratorIsValid(kbts_glyph_iterator *It)+{+ int Result = It->CurrentGlyph && kbts__GlyphIsValid(It->GlyphStorage, It->CurrentGlyph);+ return Result;+}++KBTS_EXPORT int kbts_GlyphIteratorNext(kbts_glyph_iterator *It, kbts_glyph **Glyph)+{+ int Result = 0;+ kbts_glyph *CurrentGlyph = It->CurrentGlyph;++ if(kbts_GlyphIteratorIsValid(It))+ {+ *Glyph = CurrentGlyph;++ Result = 1;+ It->CurrentGlyph = CurrentGlyph->Next;+ }++ return Result;+}++KBTS_EXPORT int kbts_FontCount(void *Data, int Size)+{+ int Result = 0;++ if(Data && (Size >= 4))+ {+ kbts_u32 Magic = *(kbts_u32 *)Data;++ if(Magic == KBTS_FOURCC('t', 't', 'c', 'f'))+ {+ kbts__ttc_header *Header = (kbts__ttc_header *)Data;++ if(Header->Magic == KBTS_FOURCC('t', 't', 'c', 'f'))+ {+ Result = (int)kbts__ByteSwap32(Header->FontCount);+ }+ }+ else if((Magic == KBTS_FOURCC('O', 'T', 'T', 'O')) ||+ (Magic == KBTS__U32BE(0x10000)) ||+ (Magic == KBTS_FOURCC('k', 'b', 't', 's')))+ {+ Result = 1;+ }+ }++ return Result;+}++static kbts__cmap_subtable_pointer kbts__SelectCmapSubtable(kbts_blob_header *Header, kbts_blob_table *CmapTable, kbts__cmap_14 **Cmap14, kbts_u16 *ResultFormat)+{+ kbts__cmap_subtable_pointer Result = KBTS__ZERO;++ if(CmapTable->Length >= sizeof(kbts__cmap))+ {+ char *TableEnd = KBTS__POINTER_OFFSET(char, Header, CmapTable->OffsetFromStartOfFile + CmapTable->Length);+ kbts__cmap *Cmap = KBTS__POINTER_OFFSET(kbts__cmap, Header, CmapTable->OffsetFromStartOfFile);++ kbts_u16 PreferredFormat = 1;+ KBTS__FOR(It, 0, Cmap->TableCount)+ {+ kbts__cmap_subtable_pointer Subtable = kbts__GetCmapSubtable(Cmap, It);+ if((char *)(Subtable.Subtable + 1) <= TableEnd)+ {+ kbts_u16 Format = *Subtable.Subtable;++ // This is kind of iffy, but the statelessness is useful for selecting+ // the cmap from an already-prepared blob without having to deal with+ // the byteswap context.+ if((Format > 0xFF) &&+ ((Format >> 8) <= 14))+ {+ Format = kbts__ByteSwap16(Format);+ *Subtable.Subtable = Format;+ }++ if(Format == 14)+ {+ if((char *)(Subtable.Subtable + sizeof(kbts__cmap_14)) <= TableEnd)+ {+ if(Cmap14)+ {+ *Cmap14 = (kbts__cmap_14 *)Subtable.Subtable;+ }+ }+ }+ else if(!Result.Subtable)+ {+ Result = Subtable;+ }+ else if(Format < KBTS__ARRAY_LENGTH(kbts__CmapFormatPrecedence))+ {+ kbts_u16 Precedence = kbts__CmapFormatPrecedence[Format];+ kbts_u16 PreferredPrecedence = kbts__CmapFormatPrecedence[PreferredFormat];++ if((Precedence > PreferredPrecedence) || ((Precedence == PreferredPrecedence) && (Subtable.PlatformId == 3)))+ {+ Result = Subtable;+ if(ResultFormat)+ {+ *ResultFormat = Format;+ }+ }+ }+ }+ }+ }++ return Result;+}++KBTS_EXPORT kbts_load_font_error kbts_LoadFont(kbts_font *Font, kbts_load_font_state *State, void *FontData, int FontDataSize, int FontIndex, int *ScratchSize_, int *OutputSize_)+{+ kbts_load_font_error Result = 0;+ kbts_un ScratchSize = 0;+ kbts_un OutputSize = 0;++ if(FontDataSize >= 4)+ {+ char *FileEnd = (char *)FontData + FontDataSize;+ kbts_u32 Magic = *(kbts_u32 *)FontData;+ kbts_un DirectoryOffset = 0;++ if(Magic == KBTS_FOURCC('t', 't', 'c', 'f'))+ {+ Magic = 0;++ if(FontDataSize >= (int)sizeof(kbts__ttc_header))+ {+ kbts__ttc_header *Header = (kbts__ttc_header *)FontData;+ kbts_un FontCount = kbts__ByteSwap32(Header->FontCount);++ if(((kbts_u32)FontIndex < FontCount) &&+ ((kbts_un)FontDataSize >= (sizeof(kbts__ttc_header) + sizeof(kbts_u32) * FontCount)))+ {+ kbts_u32 *TableDirectoryOffsets = KBTS__POINTER_AFTER(kbts_u32, Header);+ DirectoryOffset = kbts__ByteSwap32(TableDirectoryOffsets[FontIndex]);++ Magic = KBTS__U32BE(0x10000);+ }+ }+ }++ if((Magic == KBTS_FOURCC('O', 'T', 'T', 'O')) ||+ (Magic == KBTS__U32BE(0x10000)))+ {+ Result = KBTS_LOAD_FONT_ERROR_NEED_TO_CREATE_BLOB;++ State->FontData = FontData;+ State->FontDataSize = (kbts_u32)FontDataSize;++ kbts__table_directory *Directory = KBTS__POINTER_OFFSET(kbts__table_directory, FontData, DirectoryOffset);+ kbts_un DirectoryTableCount = kbts__ByteSwap16(Directory->TableCount);++ kbts__table_record *Tables = KBTS__POINTER_AFTER(kbts__table_record, Directory);++ kbts_un DirectoryTableCapacity = (kbts_un)(FileEnd - (char *)Tables) / sizeof(kbts__table_record);+ if(DirectoryTableCount <= DirectoryTableCapacity)+ {+ for(kbts_un TableIndex = 0; TableIndex < DirectoryTableCount; ++TableIndex)+ {+ kbts__table_record *Table = &Tables[TableIndex];+ kbts_u32 TableOffset = kbts__ByteSwap32(Table->Offset);+ kbts_u32 TableLength = kbts__ByteSwap32(Table->Length);++ void *TableBase = KBTS__POINTER_OFFSET(void, FontData, TableOffset);+ char *TableEnd = (char *)TableBase + TableLength;+ if(((char *)TableBase >= (char *)(Tables + DirectoryTableCount)) && (TableEnd <= FileEnd))+ {+ kbts_blob_table_id TableId = 0;++ switch(Table->Tag)+ {+ case KBTS_FOURCC('h', 'e', 'a', 'd'): TableId = KBTS_BLOB_TABLE_ID_HEAD; break;+ case KBTS_FOURCC('c', 'm', 'a', 'p'): TableId = KBTS_BLOB_TABLE_ID_CMAP; break;+ case KBTS_FOURCC('G', 'D', 'E', 'F'): TableId = KBTS_BLOB_TABLE_ID_GDEF; break;+ case KBTS_FOURCC('G', 'S', 'U', 'B'): TableId = KBTS_BLOB_TABLE_ID_GSUB; break;+ case KBTS_FOURCC('G', 'P', 'O', 'S'): TableId = KBTS_BLOB_TABLE_ID_GPOS; break;+ case KBTS_FOURCC('h', 'h', 'e', 'a'): TableId = KBTS_BLOB_TABLE_ID_HHEA; break;+ case KBTS_FOURCC('v', 'h', 'e', 'a'): TableId = KBTS_BLOB_TABLE_ID_VHEA; break;+ case KBTS_FOURCC('h', 'm', 't', 'x'): TableId = KBTS_BLOB_TABLE_ID_HMTX; break;+ case KBTS_FOURCC('v', 'm', 't', 'x'): TableId = KBTS_BLOB_TABLE_ID_VMTX; break;+ case KBTS_FOURCC('m', 'a', 'x', 'p'): TableId = KBTS_BLOB_TABLE_ID_MAXP; break;+ case KBTS_FOURCC('O', 'S', '/', '2'): TableId = KBTS_BLOB_TABLE_ID_OS2; break;+ case KBTS_FOURCC('n', 'a', 'm', 'e'): TableId = KBTS_BLOB_TABLE_ID_NAME; break;+ }++ if(TableId)+ {+ kbts_blob_table *ReadTable = &State->Tables[TableId];+ ReadTable->OffsetFromStartOfFile = TableOffset;+ ReadTable->Length = TableLength;+ }+ }+ }+ }++ {+ kbts_un TotalLookupCount = 0;+ kbts_un TotalSubtableCount = 0;++ kbts_blob_table *GsubGposTables[] = {&State->Tables[KBTS_BLOB_TABLE_ID_GSUB], &State->Tables[KBTS_BLOB_TABLE_ID_GPOS]};+ KBTS__FOR(GsubGposTableIndex, 0, KBTS__ARRAY_LENGTH(GsubGposTables))+ {+ kbts_blob_table *Table = GsubGposTables[GsubGposTableIndex];++ if(Table->Length)+ {+ kbts__gsub_gpos *GsubGpos = KBTS__POINTER_OFFSET(kbts__gsub_gpos, FontData, Table->OffsetFromStartOfFile);+ kbts_lookup_list *LookupList = KBTS__POINTER_OFFSET(kbts_lookup_list, GsubGpos, kbts__ByteSwap16(GsubGpos->LookupListOffset));+ kbts_u16 *LookupOffsets = KBTS__POINTER_AFTER(kbts_u16, LookupList);+ kbts_un LookupCount = kbts__ByteSwap16(LookupList->Count);++ KBTS__FOR(LookupIndex, 0, LookupCount)+ {+ kbts__lookup *Lookup = KBTS__POINTER_OFFSET(kbts__lookup, LookupList, kbts__ByteSwap16(LookupOffsets[LookupIndex]));++ TotalSubtableCount += kbts__ByteSwap16(Lookup->SubtableCount);+ }++ TotalLookupCount += LookupCount;+ }+ }++ State->LookupCount = (kbts_u32)TotalLookupCount;+ State->LookupSubtableCount = (kbts_u32)TotalSubtableCount;+ }++ {+ kbts_un GlyphCount = 0;++ kbts_blob_table *MaxpTable = &State->Tables[KBTS_BLOB_TABLE_ID_MAXP];+ if(MaxpTable->Length)+ {+ kbts__maxp *Maxp = KBTS__POINTER_OFFSET(kbts__maxp, FontData, MaxpTable->OffsetFromStartOfFile);++ GlyphCount = kbts__ByteSwap16(Maxp->GlyphCount);+ }++ State->GlyphCount = (kbts_u32)GlyphCount;+ }++ ScratchSize = (State->Tables[KBTS_BLOB_TABLE_ID_GSUB].Length ++ State->Tables[KBTS_BLOB_TABLE_ID_GPOS].Length ++ State->Tables[KBTS_BLOB_TABLE_ID_GDEF].Length) * sizeof(kbts_u32) / 2;++ kbts_un GlyphLookupMatrixSizeInBytes = 0;+ if(State->LookupCount &&+ State->GlyphCount)+ {+ kbts__matrix_index LastIndex = kbts__GlyphLookupMatrixIndex(State->LookupCount - 1, State->GlyphCount - 1, State->GlyphCount);+ GlyphLookupMatrixSizeInBytes = LastIndex.WordIndex * sizeof(kbts_u32);+ }+ kbts_un GlyphLookupSubtableMatrixSizeInBytes = ((((State->LookupSubtableCount * State->GlyphCount) + 7) / 8) + 3) & ~3u;+ OutputSize = sizeof(kbts_blob_header) ++ sizeof(kbts_blob_table) * KBTS_BLOB_TABLE_ID_COUNT ++ GlyphLookupMatrixSizeInBytes ++ GlyphLookupSubtableMatrixSizeInBytes ++ sizeof(kbts_u32) * State->LookupCount ++ sizeof(kbts_lookup_subtable_info) * State->LookupSubtableCount;++ KBTS__FOR(TableId, 0, KBTS_BLOB_TABLE_ID_COUNT)+ {+ OutputSize += State->Tables[TableId].Length;+ }++ *ScratchSize_ = (int)ScratchSize;+ *OutputSize_ = (int)OutputSize;++ State->ScratchSize = (kbts_u32)ScratchSize;+ State->GlyphLookupMatrixSizeInBytes = (kbts_u32)GlyphLookupMatrixSizeInBytes;+ State->GlyphLookupSubtableMatrixSizeInBytes = (kbts_u32)GlyphLookupSubtableMatrixSizeInBytes;+ State->TotalSize = (kbts_u32)OutputSize;+ }+ else if(Magic == KBTS_FOURCC('k', 'b', 't', 's'))+ {+ kbts_blob_header *Header = (kbts_blob_header *)FontData;++ if(Header->Version != KBTS_BLOB_VERSION_CURRENT)+ {+ Result = KBTS_LOAD_FONT_ERROR_INVALID_FONT;+ }++ // @Incomplete: Bounds check or something.++ Font->Blob = Header;+ kbts__cmap_subtable_pointer PreferredSubtable = kbts__SelectCmapSubtable(Header, &Header->Tables[KBTS_BLOB_TABLE_ID_CMAP], &Font->Cmap14, 0);+ Font->Cmap = PreferredSubtable.Subtable;+ }+ }++ return Result;+}++KBTS_EXPORT int kbts_FontIsValid(kbts_font *Font)+{+ int Result = !Font->Error;+ return Result;+}++static void kbts__MarkMatrixCoverage(kbts_u32 *Matrix, kbts_un TableIndex, kbts_un TableCount, kbts_un GlyphCount, kbts__coverage *Coverage, int SubtableMatrix)+{+ if(Coverage)+ {+ if(Coverage->Format == 1)+ {+ kbts_u16 *GlyphIds = KBTS__POINTER_AFTER(kbts_u16, Coverage);++ KBTS__FOR(GlyphIndex, 0, Coverage->Count)+ {+ kbts_un GlyphId = GlyphIds[GlyphIndex];+ kbts__matrix_index MatrixIndex = SubtableMatrix ?+ kbts__GlyphLookupSubtableMatrixIndex(TableIndex, TableCount, GlyphId) :+ kbts__GlyphLookupMatrixIndex(TableIndex, GlyphId, GlyphCount);++ if(GlyphId < GlyphCount)+ {+ Matrix[MatrixIndex.WordIndex] |= 1 << MatrixIndex.BitIndex;+ }+ }+ }+ else if(Coverage->Format == 2)+ {+ kbts__range_record *Ranges = KBTS__POINTER_AFTER(kbts__range_record, Coverage);++ KBTS__FOR(RangeIndex, 0, Coverage->Count)+ {+ kbts__range_record *Range = &Ranges[RangeIndex];+ KBTS__FOR(GlyphId, Range->StartGlyphId, (kbts_un)Range->EndGlyphId + 1)+ {+ kbts__matrix_index MatrixIndex = SubtableMatrix ?+ kbts__GlyphLookupSubtableMatrixIndex(TableIndex, TableCount, GlyphId) :+ kbts__GlyphLookupMatrixIndex(TableIndex, GlyphId, GlyphCount);++ if(GlyphId < GlyphCount)+ {+ Matrix[MatrixIndex.WordIndex] |= 1 << MatrixIndex.BitIndex;+ }+ }+ }+ }+ }+}++static void kbts__MarkMatrixClassDef(kbts_u32 *Matrix, kbts_un SubtableIndex, kbts_un SubtableCount, kbts_un GlyphCount, kbts_u16 *ClassDefBase, kbts_u64 *ClassesIncluded, kbts_un ClassesIncludedLength)+{+ if(ClassDefBase)+ {+ if(*ClassDefBase == 1)+ {+ kbts__class_definition_1 *ClassDef = (kbts__class_definition_1 *)ClassDefBase;+ kbts_u16 *GlyphClasses = KBTS__POINTER_AFTER(kbts_u16, ClassDef);++ KBTS__FOR(GlyphIndex, 0, ClassDef->GlyphCount)+ {+ kbts_un GlyphId = ClassDef->StartGlyphId + GlyphIndex;+ kbts_un GlyphClass = GlyphClasses[GlyphIndex];++ if((GlyphId >= (ClassesIncludedLength * 64)) ||+ (ClassesIncluded[GlyphClass / 64] & (1ull << (GlyphClass % 64))))+ {+ kbts__matrix_index SubtableMatrixIndex = kbts__GlyphLookupSubtableMatrixIndex(SubtableIndex, SubtableCount, GlyphId);+ Matrix[SubtableMatrixIndex.WordIndex] |= 1 << SubtableMatrixIndex.BitIndex;+ }+ }+ }+ else if(*ClassDefBase == 2)+ {+ kbts__class_definition_2 *ClassDef = (kbts__class_definition_2 *)ClassDefBase;+ kbts__class_range_record *Ranges = KBTS__POINTER_AFTER(kbts__class_range_record, ClassDef);++ KBTS__FOR(RangeIndex, 0, ClassDef->Count)+ {+ kbts__class_range_record *Range = &Ranges[RangeIndex];+ kbts_un RangeClass = Range->Class;++ if((RangeClass >= (ClassesIncludedLength * 64)) ||+ (ClassesIncluded[RangeClass / 64] & (1ull << (RangeClass % 64))))+ {+ kbts_un OnePastLastGlyphId = Range->EndGlyphId + 1;+ if(OnePastLastGlyphId > GlyphCount)+ {+ OnePastLastGlyphId = GlyphCount;+ }++ KBTS__FOR(GlyphId, Range->StartGlyphId, OnePastLastGlyphId)+ {+ kbts__matrix_index SubtableMatrixIndex = kbts__GlyphLookupSubtableMatrixIndex(SubtableIndex, SubtableCount, GlyphId);+ Matrix[SubtableMatrixIndex.WordIndex] |= 1 << SubtableMatrixIndex.BitIndex;+ }+ }+ }+ }+ }+}++KBTS_EXPORT kbts_load_font_error kbts_PlaceBlob(kbts_font *Font, kbts_load_font_state *State, void *ScratchMemory, void *OutputMemory)+{+ kbts_load_font_error Result = 0;++ if(!Font)+ {+ Result = KBTS_LOAD_FONT_ERROR_INVALID_FONT;+ }++ if(!ScratchMemory || !OutputMemory)+ {+ Result = KBTS_LOAD_FONT_ERROR_OUT_OF_MEMORY;+ }++ if(Result == KBTS_LOAD_FONT_ERROR_NONE)+ {+ kbts_blob_header *Header = (kbts_blob_header *)OutputMemory;+ *Header = KBTS__ZERO_TYPE(kbts_blob_header);+ Header->Magic = KBTS_FOURCC('k', 'b', 't', 's');+ Header->Version = 1;+ Header->LookupCount = State->LookupCount;+ Header->LookupSubtableCount = State->LookupSubtableCount;++ // Stamp packed font data.+ char *OutData = KBTS__POINTER_AFTER(char, Header);+ KBTS__FOR(TableId, 0, KBTS_BLOB_TABLE_ID_COUNT)+ {+ kbts_blob_table InTable = State->Tables[TableId];+ kbts_blob_table *OutTable = &Header->Tables[TableId];++ OutTable->OffsetFromStartOfFile = KBTS__POINTER_DIFF32(OutData, Header);+ OutTable->Length = InTable.Length;++ void *InData = KBTS__POINTER_OFFSET(void, State->FontData, InTable.OffsetFromStartOfFile);+ KBTS_MEMCPY(OutData, InData, InTable.Length);++ OutData += InTable.Length;+ }++ // Byteswap it.++ {+ kbts_blob_table *HeadTable = &Header->Tables[KBTS_BLOB_TABLE_ID_HEAD];++ if(HeadTable->Length)+ {+ if(HeadTable->Length >= sizeof(kbts__head))+ {+ kbts__head *Head = KBTS__POINTER_OFFSET(kbts__head, Header, HeadTable->OffsetFromStartOfFile);++ kbts__ByteSwapArray16Unchecked(&Head->Major, 2);+ kbts__ByteSwapArray32Unchecked(&Head->Revision, 2);+ // We do not swap the magic number.+ kbts__ByteSwapArray16Unchecked(&Head->Flags, 2);+ // We do not swap file times.+ kbts__ByteSwapArray16Unchecked((kbts_u16 *)&Head->XMin, 9);+ }+ else+ {+ Result = KBTS_LOAD_FONT_ERROR_INVALID_FONT;+ }+ }+ }++ Font->Blob = Header;++ {+ kbts_blob_table *CmapTable = &Header->Tables[KBTS_BLOB_TABLE_ID_CMAP];++ if(CmapTable->Length)+ {+ if(CmapTable->Length >= sizeof(kbts__cmap))+ {+ int TableValid = 0;+ char *TableEnd = KBTS__POINTER_OFFSET(char, Header, CmapTable->OffsetFromStartOfFile + CmapTable->Length);+ kbts__cmap *Cmap = KBTS__POINTER_OFFSET(kbts__cmap, Header, CmapTable->OffsetFromStartOfFile);+ Cmap->Version = kbts__ByteSwap16(Cmap->Version);+ Cmap->TableCount = kbts__ByteSwap16(Cmap->TableCount);++ kbts__encoding_record *Records = KBTS__POINTER_AFTER(kbts__encoding_record, Cmap);++ if((char *)(Records + Cmap->TableCount) <= TableEnd)+ {+ KBTS__FOR(It, 0, Cmap->TableCount)+ {+ kbts__encoding_record *Record = &Records[It];+ Record->EncodingId = kbts__ByteSwap16(Record->EncodingId);+ Record->PlatformId = kbts__ByteSwap16(Record->PlatformId);+ Record->SubtableOffset = kbts__ByteSwap32(Record->SubtableOffset);+ }++ kbts_u16 PreferredFormat = 1;++ kbts__cmap_subtable_pointer PreferredSubtable = kbts__SelectCmapSubtable(Header, CmapTable, &Font->Cmap14, &PreferredFormat);+ if(PreferredSubtable.Subtable)+ {+ switch(*PreferredSubtable.Subtable)+ {+ case 0:+ {+ kbts__cmap_0 *Cmap0 = (kbts__cmap_0 *)PreferredSubtable.Subtable;+ if((char *)(Cmap0 + 1) <= TableEnd)+ {+ Cmap0->Length = kbts__ByteSwap16(Cmap0->Length);+ Cmap0->Language = kbts__ByteSwap16(Cmap0->Language);+ TableValid = 1;+ }+ }+ break;++ case 2:+ {+ kbts__cmap_2 *Cmap2 = (kbts__cmap_2 *)PreferredSubtable.Subtable;+ if(kbts__ByteSwapArray16(&Cmap2->Length, 258, TableEnd))+ {+ kbts_un SubHeaderCount = 0;+ KBTS__FOR(It, 0, 256)+ {+ kbts_un SubHeaderIndex = Cmap2->SubHeaderKeys[It];+ SubHeaderCount = KBTS__MAX(SubHeaderCount, SubHeaderIndex + 1);+ }++ kbts__sub_header *SubHeaders = KBTS__POINTER_AFTER(kbts__sub_header, Cmap2);+ if(kbts__ByteSwapArray16(&SubHeaders->FirstCode, 4 * SubHeaderCount, TableEnd))+ {+ kbts_u16 *GlyphIds = (kbts_u16 *)(SubHeaders + SubHeaderCount);++ kbts_sn GlyphIdCount = 0;+ KBTS__FOR(It, 0, SubHeaderCount)+ {+ kbts__sub_header *SubHeader = &SubHeaders[It];++ kbts_u16 *OnePastLastGlyphId = &SubHeader->IdRangeOffset + SubHeader->IdRangeOffset / 2 + SubHeader->EntryCount;+ GlyphIdCount = KBTS__MAX(GlyphIdCount, OnePastLastGlyphId - GlyphIds);+ }++ if(kbts__ByteSwapArray16(GlyphIds, (kbts_un)GlyphIdCount, TableEnd))+ {+ TableValid = 1;+ }+ }+ }+ }+ break;++ case 4:+ {+ kbts__cmap_4 *Cmap4 = (kbts__cmap_4 *)PreferredSubtable.Subtable;+ if(kbts__ByteSwapArray16(&Cmap4->Length, 5, TableEnd) &&+ kbts__ByteSwapArray16(KBTS__POINTER_AFTER(kbts_u16, Cmap4), Cmap4->SegmentCountTimesTwo * 2 + 1, TableEnd))+ {+ kbts_un SegmentCount = Cmap4->SegmentCountTimesTwo / 2;+ kbts_u16 *EndCodes = KBTS__POINTER_AFTER(kbts_u16, Cmap4);+ kbts_u16 *StartCodes = EndCodes + SegmentCount + 1;+ kbts_s16 *IdDeltas = (kbts_s16 *)(StartCodes + SegmentCount);+ kbts_u16 *IdRangeOffsets = (kbts_u16 *)(IdDeltas + SegmentCount);+ kbts_u16 *GlyphIds = IdRangeOffsets + SegmentCount;++ kbts_sn GlyphIdCount = 0;++ KBTS__FOR(SegmentIndex, 0, SegmentCount)+ {+ kbts_u16 Offset = IdRangeOffsets[SegmentIndex];++ if(Offset)+ {+ kbts_u16 *IdLookup = &IdRangeOffsets[SegmentIndex] + (EndCodes[SegmentIndex] - StartCodes[SegmentIndex] + 1) + Offset / 2;++ GlyphIdCount = KBTS__MAX(GlyphIdCount, (IdLookup - GlyphIds));+ }+ }++ if(kbts__ByteSwapArray16(GlyphIds, (kbts_un)GlyphIdCount, TableEnd))+ {+ TableValid = 1;+ }+ }+ }+ break;++ case 6:+ {+ kbts__cmap_6 *Cmap6 = (kbts__cmap_6 *)PreferredSubtable.Subtable;+ if(kbts__ByteSwapArray16(&Cmap6->Length, 4, TableEnd) &&+ kbts__ByteSwapArray16(KBTS__POINTER_AFTER(kbts_u16, Cmap6), Cmap6->EntryCount, TableEnd))+ {+ TableValid = 1;+ }+ }+ break;++ case 12:+ {+ kbts__cmap_12_13 *Cmap12 = (kbts__cmap_12_13 *)PreferredSubtable.Subtable;+ if(kbts__ByteSwapArray32(&Cmap12->Length, 3, TableEnd) &&+ kbts__ByteSwapArray32(KBTS__POINTER_AFTER(kbts_u32, Cmap12), Cmap12->GroupCount * 3, TableEnd))+ {+ TableValid = 1;+ }+ }+ break;+ }++ Font->Cmap = PreferredSubtable.Subtable;+ }+ }++ if(!TableValid)+ {+ Result = KBTS_LOAD_FONT_ERROR_INVALID_FONT;+ }+ }+ else+ {+ Result = KBTS_LOAD_FONT_ERROR_INVALID_FONT;+ }+ }+ }++ {+ kbts_blob_table *GdefTable = &Header->Tables[KBTS_BLOB_TABLE_ID_GDEF];++ if(GdefTable->Length)+ {+ kbts__gdef *Gdef = KBTS__POINTER_OFFSET(kbts__gdef, Header, GdefTable->OffsetFromStartOfFile);+ char *TableEnd = KBTS__POINTER_OFFSET(char, Header, GdefTable->OffsetFromStartOfFile + GdefTable->Length);++ if(kbts__ByteSwapArray16(&Gdef->Major, 6, TableEnd))+ {+ if(Gdef->Minor >= 2)+ {+ if(GdefTable->Length >= 14)+ {+ Gdef->MarkGlyphSetsDefinitionOffset = kbts__ByteSwap16(Gdef->MarkGlyphSetsDefinitionOffset);++ if(Gdef->Minor == 3)+ {+ if(GdefTable->Length >= sizeof(kbts__gdef))+ {+ // @Incomplete+ Gdef->ItemVariationStoreOffset = kbts__ByteSwap32(Gdef->ItemVariationStoreOffset);+ }+ else+ {+ Result = KBTS_LOAD_FONT_ERROR_INVALID_FONT;+ }+ }+ }+ else+ {+ Result = KBTS_LOAD_FONT_ERROR_INVALID_FONT;+ }+ }+ }+ else+ {+ Result = KBTS_LOAD_FONT_ERROR_INVALID_FONT;+ }+ }+ }++ {+ kbts_blob_table_id HeaTableIds[2] = {KBTS_BLOB_TABLE_ID_HHEA, KBTS_BLOB_TABLE_ID_VHEA};+ KBTS__FOR(HeaTableIndex, 0, KBTS__ARRAY_LENGTH(HeaTableIds))+ {+ kbts_blob_table *HeaTable = &Header->Tables[HeaTableIds[HeaTableIndex]];++ if(HeaTable->Length)+ {+ kbts__hea *Hea = KBTS__POINTER_OFFSET(kbts__hea, Header, HeaTable->OffsetFromStartOfFile);+ char *TableEnd = KBTS__POINTER_OFFSET(char, Header, HeaTable->OffsetFromStartOfFile + HeaTable->Length);++ if(!kbts__ByteSwapArray16((kbts_u16 *)Hea, sizeof(kbts__hea) / sizeof(kbts_u16), TableEnd))+ {+ Result = KBTS_LOAD_FONT_ERROR_INVALID_FONT;+ }+ }+ }+ }++ {+ kbts_blob_table_id MtxTableIds[2] = {KBTS_BLOB_TABLE_ID_HMTX, KBTS_BLOB_TABLE_ID_VMTX};++ KBTS__FOR(MtxTableIndex, 0, KBTS__ARRAY_LENGTH(MtxTableIds))+ {+ kbts_blob_table *MtxTable = &Header->Tables[MtxTableIds[MtxTableIndex]];++ if(MtxTable->Length)+ {+ kbts_u16 *Mtx = KBTS__POINTER_OFFSET(kbts_u16, Header, MtxTable->OffsetFromStartOfFile);+ kbts__ByteSwapArray16Unchecked(Mtx, MtxTable->Length / sizeof(kbts_u16));+ }+ }+ }++ {+ kbts_blob_table *MaxpTable = &Header->Tables[KBTS_BLOB_TABLE_ID_MAXP];++ if(MaxpTable->Length)+ {+ if(MaxpTable->Length >= 6)+ {+ kbts__maxp *Maxp = KBTS__POINTER_OFFSET(kbts__maxp, Header, MaxpTable->OffsetFromStartOfFile);+ char *TableEnd = KBTS__POINTER_OFFSET(char, Header, MaxpTable->OffsetFromStartOfFile + MaxpTable->Length);++ Maxp->Major = kbts__ByteSwap16(Maxp->Major);+ Maxp->Minor = kbts__ByteSwap16(Maxp->Minor);++ kbts_un U16Count = 0;+ if(!Maxp->Major && (Maxp->Minor == 0x5000))+ {+ U16Count = 1;+ }+ else if((Maxp->Major == 1) && !Maxp->Minor)+ {+ U16Count = 14;+ }++ if(kbts__ByteSwapArray16(&Maxp->GlyphCount, U16Count, TableEnd))+ {+ Header->GlyphCount = Maxp->GlyphCount;+ }+ else+ {+ Result = KBTS_LOAD_FONT_ERROR_INVALID_FONT;+ }+ }+ else+ {+ Result = KBTS_LOAD_FONT_ERROR_INVALID_FONT;+ }+ }+ }++ {+ kbts_blob_table *Os2Table = &Header->Tables[KBTS_BLOB_TABLE_ID_OS2];++ if(Os2Table->Length)+ {+ kbts__os2 *Os2 = KBTS__POINTER_OFFSET(kbts__os2, Header, Os2Table->OffsetFromStartOfFile);+ kbts_un Length = Os2Table->Length;++ if(Length >= 68)+ {+ kbts__ByteSwapArray16Unchecked(&Os2->Version, 16);+ kbts__ByteSwapArray32Unchecked(Os2->UnicodeRange, 4);+ kbts__ByteSwapArray16Unchecked(&Os2->Selection, 3);++ kbts_un Version = Os2->Version;++ if(Length >= 78)+ {+ kbts__ByteSwapArray16Unchecked((kbts_u16 *)&Os2->TypoAscender, 5);++ if(Version >= 1)+ {+ if(Length >= 86)+ {+ kbts__ByteSwapArray32Unchecked(Os2->CodePageRange, 2);++ if(Version >= 2)+ {+ if(Length >= 96)+ {+ kbts__ByteSwapArray16Unchecked((kbts_u16 *)&Os2->Height, 5);++ if(Version >= 5)+ {+ if(Length >= 100)+ {+ kbts__ByteSwapArray16Unchecked(&Os2->LowerOpticalPointSize, 2);+ }+ else+ {+ Result = KBTS_LOAD_FONT_ERROR_INVALID_FONT;+ }+ }+ }+ else+ {+ Result = KBTS_LOAD_FONT_ERROR_INVALID_FONT;+ }+ }+ }+ else+ {+ Result = KBTS_LOAD_FONT_ERROR_INVALID_FONT;+ }+ }+ }+ }+ else+ {+ Result = KBTS_LOAD_FONT_ERROR_INVALID_FONT;+ }+ }+ // We should normally set Result to INVALID_FONT if there is no OS/2 table.+ // However, one Harfbuzz test has a font with no OS/2 table.+ }++ {+ kbts_blob_table *NameTable = &Header->Tables[KBTS_BLOB_TABLE_ID_NAME];++ if(NameTable->Length >= sizeof(kbts__name))+ {+ kbts__name *Name = KBTS__POINTER_OFFSET(kbts__name, Header, NameTable->OffsetFromStartOfFile);+ char *TableEnd = KBTS__POINTER_OFFSET(char, Name, NameTable->Length);++ kbts__ByteSwapArray16Unchecked(&Name->Version, 3);++ kbts__name_record *NameRecords = KBTS__POINTER_AFTER(kbts__name_record, Name);++ kbts_un U16Count = Name->Count * 6;+ if(!kbts__ByteSwapArray16(&NameRecords->PlatformId, U16Count, TableEnd))+ {+ Result = KBTS_LOAD_FONT_ERROR_INVALID_FONT;+ }+ }+ // We should normally set Result to INVALID_FONT if there is no name table.+ // However, one Harfbuzz test has a font with no name table.+ }++ kbts__byteswap_context ByteSwapContext = KBTS__ZERO;+ ByteSwapContext.FileBase = (char *)Header;+ ByteSwapContext.FileEnd = (char *)Header + State->TotalSize;+ ByteSwapContext.PointerCapacity = State->ScratchSize / sizeof(kbts_u32);+ ByteSwapContext.Pointers = (kbts_u32 *)ScratchMemory;++ kbts_blob_table *GdefTable = &Header->Tables[KBTS_BLOB_TABLE_ID_GDEF];+ if(GdefTable->Length)+ {+ kbts__gdef *Gdef = KBTS__POINTER_OFFSET(kbts__gdef, Header, GdefTable->OffsetFromStartOfFile);++ if(Gdef->ClassDefinitionOffset)+ {+ kbts_u16 *ClassDefBase = KBTS__POINTER_OFFSET(kbts_u16, Gdef, Gdef->ClassDefinitionOffset);+ kbts__ByteSwapClassDefinition(&ByteSwapContext, ClassDefBase);+ }++ if(Gdef->MarkAttachmentClassDefinitionOffset)+ {+ kbts_u16 *ClassDefBase = KBTS__POINTER_OFFSET(kbts_u16, Gdef, Gdef->MarkAttachmentClassDefinitionOffset);+ kbts__ByteSwapClassDefinition(&ByteSwapContext, ClassDefBase);+ }++ if((Gdef->Minor >= 2) && Gdef->MarkGlyphSetsDefinitionOffset)+ {+ kbts__mark_glyph_sets *MarkGlyphSets = KBTS__POINTER_OFFSET(kbts__mark_glyph_sets, Gdef, Gdef->MarkGlyphSetsDefinitionOffset);+ kbts__ByteSwapArray16Context(&MarkGlyphSets->Format, 2, &ByteSwapContext);+ if(MarkGlyphSets->Format == 1)+ {+ kbts_u32 *CoverageOffsets = KBTS__POINTER_AFTER(kbts_u32, MarkGlyphSets);+ kbts__ByteSwapArray32Context(CoverageOffsets, MarkGlyphSets->MarkGlyphSetCount, &ByteSwapContext);++ KBTS__FOR(MarkGlyphSetIndex, 0, MarkGlyphSets->MarkGlyphSetCount)+ {+ kbts__coverage *Coverage = KBTS__POINTER_OFFSET(kbts__coverage, MarkGlyphSets, CoverageOffsets[MarkGlyphSetIndex]);+ kbts__ByteSwapCoverage(&ByteSwapContext, Coverage);+ }+ }+ }+ }++ kbts__gsub_gpos *Gsub = kbts__BlobTableDataType(Header, KBTS_BLOB_TABLE_ID_GSUB, kbts__gsub_gpos);+ kbts__gsub_gpos *Gpos = kbts__BlobTableDataType(Header, KBTS_BLOB_TABLE_ID_GPOS, kbts__gsub_gpos);+ kbts__gdef *Gdef = kbts__BlobTableDataType(Header, KBTS_BLOB_TABLE_ID_GDEF, kbts__gdef);++ if(Gsub)+ {+ kbts__ByteSwapGsubGposCommon(&ByteSwapContext, Gsub);++ kbts_lookup_list *LookupList = kbts__GetLookupList(Gsub);+ LookupList->Count = kbts__ByteSwap16(LookupList->Count);+ kbts__ByteSwapArray16Context(KBTS__POINTER_AFTER(kbts_u16, LookupList), LookupList->Count, &ByteSwapContext);++ KBTS__FOR(LookupIndex, 0, LookupList->Count)+ {+ kbts__lookup *PackedLookup = kbts__GetLookup(LookupList, LookupIndex);++ KBTS_DUMPF("GSUB Lookup %llu:\n", LookupIndex);++ if(kbts__ByteSwapLookup(&ByteSwapContext, PackedLookup))+ {+ kbts__unpacked_lookup Lookup = kbts__UnpackLookup(Gdef, PackedLookup);+ KBTS_DUMPF(" Flags %u\n", Lookup.Flags);++ KBTS__FOR(SubstitutionIndex, 0, Lookup.SubtableCount)+ {+ kbts_u16 *Base = KBTS__POINTER_OFFSET(kbts_u16, PackedLookup, Lookup.SubtableOffsets[SubstitutionIndex]);++ KBTS_DUMPF(" Subtable %llu:\n", SubstitutionIndex);++ kbts__ByteSwapGsubLookupSubtable(&ByteSwapContext, Lookup.Type, Base);+ }+ }+ }+ }++ if(Gpos)+ {+ kbts__ByteSwapGsubGposCommon(&ByteSwapContext, Gpos);++ kbts_lookup_list *LookupList = kbts__GetLookupList(Gpos);+ LookupList->Count = kbts__ByteSwap16(LookupList->Count);+ kbts__ByteSwapArray16Context(KBTS__POINTER_AFTER(kbts_u16, LookupList), LookupList->Count, &ByteSwapContext);++ KBTS__FOR(LookupIndex, 0, LookupList->Count)+ {+ kbts__lookup *PackedLookup = kbts__GetLookup(LookupList, LookupIndex);++ KBTS_DUMPF("GPOS Lookup %llu:\n", LookupIndex);++ if(kbts__ByteSwapLookup(&ByteSwapContext, PackedLookup))+ {+ kbts__unpacked_lookup Lookup = kbts__UnpackLookup(Gdef, PackedLookup);++ KBTS_DUMPF(" Flags %x\n", Lookup.Flags);++ KBTS__FOR(SubstitutionIndex, 0, Lookup.SubtableCount)+ {+ kbts_u16 *Base = KBTS__POINTER_OFFSET(kbts_u16, PackedLookup, Lookup.SubtableOffsets[SubstitutionIndex]);++ KBTS_DUMPF(" Subtable %llu:\n", (kbts_un)SubstitutionIndex);++ kbts__ByteSwapGposLookupSubtable(&ByteSwapContext, LookupList, Lookup.Type, Base);+ }+ }+ }+ }++ // At this point, we are done byteswapping the file, so we can start reusing scratch memory.++ // Bake our own data.++ if(!Result && Header->Tables[KBTS_BLOB_TABLE_ID_MAXP].Length)+ {+ kbts_un GlyphCount = Header->GlyphCount;+ kbts_un LookupCount = Header->LookupCount;+ kbts_un SubtableCount = Header->LookupSubtableCount;++ kbts_u32 *GlyphLookupMatrix = (kbts_u32 *)OutData;+ kbts_u32 *GlyphLookupSubtableMatrix = KBTS__POINTER_OFFSET(kbts_u32, GlyphLookupMatrix, State->GlyphLookupMatrixSizeInBytes);+ kbts_u32 *LookupSubtableIndexOffsets = KBTS__POINTER_OFFSET(kbts_u32, GlyphLookupSubtableMatrix, State->GlyphLookupSubtableMatrixSizeInBytes);+ kbts_lookup_subtable_info *SubtableInfos = KBTS__POINTER_OFFSET(kbts_lookup_subtable_info, LookupSubtableIndexOffsets, sizeof(kbts_u32) * Header->LookupCount);++ KBTS_MEMSET(GlyphLookupMatrix, 0, State->GlyphLookupMatrixSizeInBytes ++ State->GlyphLookupSubtableMatrixSizeInBytes ++ sizeof(kbts_u32) * Header->LookupCount ++ sizeof(kbts_lookup_subtable_info) * Header->LookupSubtableCount);++ kbts_un GposLookupIndexOffset = 0;+ kbts_un RunningLookupIndex = 0;+ kbts_un RunningSubtableIndex = 0;++ kbts_blob_table_id TableIds[2] = {KBTS_BLOB_TABLE_ID_GSUB, KBTS_BLOB_TABLE_ID_GPOS};+ KBTS__FOR(TableIdIndex, 0, KBTS__ARRAY_LENGTH(TableIds))+ {+ kbts_blob_table_id TableId = TableIds[TableIdIndex];+ kbts_blob_table *Table = &Header->Tables[TableId];++ if(Table->Length)+ {+ kbts__gsub_gpos *ShapingTable = KBTS__POINTER_OFFSET(kbts__gsub_gpos, Header, Table->OffsetFromStartOfFile);+ int InGpos = (TableId == KBTS_BLOB_TABLE_ID_GPOS);+ kbts_shaping_table ShapingTableId = (kbts_shaping_table)(InGpos ? KBTS_SHAPING_TABLE_GPOS : KBTS_SHAPING_TABLE_GSUB);++ if(InGpos)+ {+ GposLookupIndexOffset = RunningLookupIndex;+ }++ if(ShapingTable)+ {+ kbts_lookup_list *LookupList = kbts__GetLookupList(ShapingTable);+ KBTS__FOR(LookupIndex, 0, LookupList->Count)+ {+ kbts__lookup *PackedLookup = kbts__GetLookup(LookupList, LookupIndex);+ kbts__unpacked_lookup Lookup = kbts__UnpackLookup(Gdef, PackedLookup);++ LookupSubtableIndexOffsets[RunningLookupIndex] = (kbts_u32)RunningSubtableIndex;++ KBTS__FOR(SubtableIndex, 0, Lookup.SubtableCount)+ {+ kbts_lookup_subtable_info SubtableInfo = KBTS__ZERO;+ kbts_u16 LookupType = Lookup.Type;+ kbts_u16 *Base = KBTS__POINTER_OFFSET(kbts_u16, PackedLookup, Lookup.SubtableOffsets[SubtableIndex]);++ while((!InGpos && (LookupType == 7)) ||+ (InGpos && (LookupType == 9)))+ {+ kbts__extension *Extension = (kbts__extension *)Base;++ // CAREFUL: Here, we remap LookupType only.+ // Do not use Lookup.Type beyond this point!+ LookupType = Extension->LookupType;+ Base = KBTS__POINTER_OFFSET(kbts_u16, Extension, Extension->Offset);+ }++ kbts__coverage *Coverage = 0;++ if(kbts__LookupBeginsWithCoverage(ShapingTableId, LookupType, Base[0]))+ {+ Coverage = KBTS__POINTER_OFFSET(kbts__coverage, Base, Base[1]);+ }++ if(!InGpos && (LookupType == 4))+ {+ kbts__ligature_substitution *Subst = (kbts__ligature_substitution *)Base;+ KBTS__FOR(SetIndex, 0, Subst->LigatureSetCount)+ {+ kbts__ligature_set *Set = kbts__GetLigatureSet(Subst, SetIndex);+ KBTS__FOR(LigatureIndex, 0, Set->Count)+ {+ kbts__ligature *Ligature = kbts__GetLigature(Set, LigatureIndex);+ kbts_u16 *Ids = KBTS__POINTER_AFTER(kbts_u16, Ligature);++ KBTS__FOR(IdIndex, 1, Ligature->ComponentCount)+ {+ kbts_un GlyphId = Ids[IdIndex - 1];++ kbts__matrix_index SubtableMatrixIndex = kbts__GlyphLookupSubtableMatrixIndex(RunningSubtableIndex, SubtableCount, GlyphId);+ GlyphLookupSubtableMatrix[SubtableMatrixIndex.WordIndex] |= 1 << SubtableMatrixIndex.BitIndex;+ }++ SubtableInfo.MinimumFollowupPlusOne = KBTS__MIN(SubtableInfo.MinimumFollowupPlusOne - 1, Ligature->ComponentCount - 1) + 1;+ }+ }+ }+ else if((!InGpos && (LookupType == 5)) ||+ (InGpos && (LookupType == 7)))+ {+ switch(Base[0])+ {+ case 1:+ {+ kbts__sequence_context_1 *Subst = (kbts__sequence_context_1 *)Base;+ KBTS__FOR(SetIndex, 0, Subst->SeqRuleSetCount)+ {+ kbts__sequence_rule_set *Set = kbts__GetSequenceRuleSet(Subst, SetIndex);++ if(Set)+ {+ KBTS__FOR(RuleIndex, 0, Set->Count)+ {+ kbts__sequence_rule *Rule = kbts__GetSequenceRule(Set, RuleIndex);+ SubtableInfo.MinimumFollowupPlusOne = KBTS__MIN(SubtableInfo.MinimumFollowupPlusOne - 1, Rule->GlyphCount - 1) + 1;++ kbts_u16 *SequenceGlyphIds = KBTS__POINTER_AFTER(kbts_u16, Rule);+ KBTS__FOR(InputIndex, 1, Rule->GlyphCount)+ {+ kbts_un GlyphId = SequenceGlyphIds[InputIndex - 1];++ kbts__matrix_index SubtableMatrixIndex = kbts__GlyphLookupSubtableMatrixIndex(RunningSubtableIndex, SubtableCount, GlyphId);+ GlyphLookupSubtableMatrix[SubtableMatrixIndex.WordIndex] |= 1 << SubtableMatrixIndex.BitIndex;+ }+ }+ }+ }+ } break;++ case 2:+ {+ kbts__sequence_context_2 *Subst = (kbts__sequence_context_2 *)Base;+ kbts_u16 *ClassDefBase = KBTS__POINTER_OFFSET(kbts_u16, Subst, Subst->ClassDefOffset);++ kbts_u64 ClassesIncluded[16] = KBTS__ZERO;++ KBTS__FOR(SetIndex, 0, Subst->ClassSequenceRuleSetCount)+ {+ kbts__class_sequence_rule_set *Set = kbts__GetClassSequenceRuleSet(Subst, SetIndex);+ if(Set)+ {+ KBTS__FOR(RuleIndex, 0, Set->Count)+ {+ kbts__class_sequence_rule *Rule = kbts__GetClassSequenceRule(Set, RuleIndex);+ kbts_u16 *SequenceClasses = KBTS__POINTER_AFTER(kbts_u16, Rule);++ SubtableInfo.MinimumFollowupPlusOne = KBTS__MIN(SubtableInfo.MinimumFollowupPlusOne - 1, Rule->GlyphCount - 1) + 1;++ KBTS__FOR(SequenceIndex, 1, Rule->GlyphCount)+ {+ kbts_un Class = SequenceClasses[SequenceIndex - 1];++ if(Class < (KBTS__ARRAY_LENGTH(ClassesIncluded) * 64))+ {+ ClassesIncluded[Class / 64] |= 1ull << (Class % 64);+ }+ }+ }+ }+ }++ kbts__MarkMatrixClassDef(GlyphLookupSubtableMatrix, RunningSubtableIndex, SubtableCount, GlyphCount, ClassDefBase, ClassesIncluded, KBTS__ARRAY_LENGTH(ClassesIncluded));+ } break;++ case 3:+ {+ kbts__sequence_context_3 *Subst = (kbts__sequence_context_3 *)Base;+ kbts_u16 *CoverageOffsets = KBTS__POINTER_AFTER(kbts_u16, Subst);++ SubtableInfo.MinimumFollowupPlusOne = KBTS__MIN(SubtableInfo.MinimumFollowupPlusOne - 1, Subst->GlyphCount - 1) + 1;++ KBTS__FOR(CoverageIndex, 1, Subst->GlyphCount)+ {+ kbts__coverage *SubstCoverage = KBTS__POINTER_OFFSET(kbts__coverage, Subst, CoverageOffsets[CoverageIndex]);++ kbts__MarkMatrixCoverage(GlyphLookupSubtableMatrix, RunningSubtableIndex, SubtableCount, GlyphCount, SubstCoverage, 1);+ }++ Coverage = KBTS__POINTER_OFFSET(kbts__coverage, Subst, CoverageOffsets[0]);+ } break;+ }+ }+ else if((!InGpos && (LookupType == 6)) ||+ (InGpos && (LookupType == 8)))+ {+ switch(Base[0])+ {+ case 1:+ {+ kbts__chained_sequence_context_1 *Subst = (kbts__chained_sequence_context_1 *)Base;+ kbts_u16 *ChainedSequenceRuleSetOffsets = KBTS__POINTER_AFTER(kbts_u16, Subst);++ KBTS__FOR(SetIndex, 0, Subst->ChainedSequenceRuleSetCount)+ {+ kbts__chained_sequence_rule_set *Set = KBTS__POINTER_OFFSET(kbts__chained_sequence_rule_set, Subst, ChainedSequenceRuleSetOffsets[SetIndex]);+ KBTS__FOR(RuleIndex, 0, Set->Count)+ {+ kbts__chained_sequence_rule *Rule = kbts__GetChainedClassSequenceRule(Set, RuleIndex);+ kbts__unpacked_chained_sequence_rule Unpacked = kbts__UnpackChainedSequenceRule(Rule, 0);++ SubtableInfo.MinimumBacktrackPlusOne = KBTS__MIN(SubtableInfo.MinimumBacktrackPlusOne - 1, Unpacked.BacktrackCount) + 1;+ SubtableInfo.MinimumFollowupPlusOne = KBTS__MIN(SubtableInfo.MinimumFollowupPlusOne - 1, Unpacked.InputCount - 1 + Unpacked.LookaheadCount) + 1;++ KBTS__FOR(BacktrackIndex, 0, Unpacked.BacktrackCount)+ {+ kbts_un GlyphId = Unpacked.Backtrack[BacktrackIndex];+ kbts__matrix_index SubtableMatrixIndex = kbts__GlyphLookupSubtableMatrixIndex(RunningSubtableIndex, SubtableCount, GlyphId);+ GlyphLookupSubtableMatrix[SubtableMatrixIndex.WordIndex] |= 1 << SubtableMatrixIndex.BitIndex;+ }++ KBTS__FOR(InputIndex, 1, Unpacked.InputCount)+ {+ kbts_un GlyphId = Unpacked.Input[InputIndex - 1];+ kbts__matrix_index SubtableMatrixIndex = kbts__GlyphLookupSubtableMatrixIndex(RunningSubtableIndex, SubtableCount, GlyphId);+ GlyphLookupSubtableMatrix[SubtableMatrixIndex.WordIndex] |= 1 << SubtableMatrixIndex.BitIndex;+ }++ KBTS__FOR(LookaheadIndex, 0, Unpacked.LookaheadCount)+ {+ kbts_un GlyphId = Unpacked.Lookahead[LookaheadIndex];+ kbts__matrix_index SubtableMatrixIndex = kbts__GlyphLookupSubtableMatrixIndex(RunningSubtableIndex, SubtableCount, GlyphId);+ GlyphLookupSubtableMatrix[SubtableMatrixIndex.WordIndex] |= 1 << SubtableMatrixIndex.BitIndex;+ }+ }+ }+ } break;++ case 2:+ {+ kbts__chained_sequence_context_2 *Subst = (kbts__chained_sequence_context_2 *)Base;+ kbts_un BacktrackClassDefOffset = Subst->BacktrackClassDefOffset;+ kbts_un InputClassDefOffset = Subst->InputClassDefOffset;+ kbts_un LookaheadClassDefOffset = Subst->LookaheadClassDefOffset;+ kbts_u16 *BacktrackClassDefinition = 0;+ if(BacktrackClassDefOffset)+ {+ BacktrackClassDefinition = KBTS__POINTER_OFFSET(kbts_u16, Subst, BacktrackClassDefOffset);+ }+ kbts_u16 *InputClassDefinition = 0;+ if(InputClassDefOffset)+ {+ InputClassDefinition = KBTS__POINTER_OFFSET(kbts_u16, Subst, InputClassDefOffset);+ }+ kbts_u16 *LookaheadClassDefinition = 0;+ if(LookaheadClassDefOffset)+ {+ LookaheadClassDefinition = KBTS__POINTER_OFFSET(kbts_u16, Subst, LookaheadClassDefOffset);+ }++ kbts_u64 BacktrackClassesIncluded[16] = KBTS__ZERO;+ kbts_u64 InputClassesIncluded[16] = KBTS__ZERO;+ kbts_u64 LookaheadClassesIncluded[16] = KBTS__ZERO;++ KBTS__FOR(SetIndex, 0, Subst->ChainedClassSequenceRuleSetCount)+ {+ kbts__chained_sequence_rule_set *Set = kbts__GetChainedClassSequenceRuleSet(Subst, SetIndex);+ if(Set)+ {+ KBTS__FOR(RuleIndex, 0, Set->Count)+ {+ kbts__chained_sequence_rule *Rule = kbts__GetChainedSequenceRule(Set, RuleIndex);+ kbts__unpacked_chained_sequence_rule Unpacked = kbts__UnpackChainedSequenceRule(Rule, 0);++ SubtableInfo.MinimumBacktrackPlusOne = KBTS__MIN(SubtableInfo.MinimumBacktrackPlusOne - 1, Unpacked.BacktrackCount) + 1;+ SubtableInfo.MinimumFollowupPlusOne = KBTS__MIN(SubtableInfo.MinimumFollowupPlusOne - 1, Unpacked.InputCount - 1 + Unpacked.LookaheadCount) + 1;++ KBTS__FOR(BacktrackIndex, 0, Unpacked.BacktrackCount)+ {+ kbts_un Class = Unpacked.Backtrack[BacktrackIndex];+ if(Class < (KBTS__ARRAY_LENGTH(BacktrackClassesIncluded) * 64))+ {+ BacktrackClassesIncluded[Class / 64] |= 1ull << (Class % 64);+ }+ }++ KBTS__FOR(InputIndex, 1, Unpacked.InputCount)+ {+ kbts_un Class = Unpacked.Input[InputIndex - 1];+ if(Class < (KBTS__ARRAY_LENGTH(InputClassesIncluded) * 64))+ {+ InputClassesIncluded[Class / 64] |= 1ull << (Class % 64);+ }+ }++ KBTS__FOR(LookaheadIndex, 0, Unpacked.LookaheadCount)+ {+ kbts_un Class = Unpacked.Lookahead[LookaheadIndex];+ if(Class < (KBTS__ARRAY_LENGTH(LookaheadClassesIncluded) * 64))+ {+ LookaheadClassesIncluded[Class / 64] |= 1ull << (Class % 64);+ }+ }+ }+ }+ }++ kbts__MarkMatrixClassDef(GlyphLookupSubtableMatrix, RunningSubtableIndex, SubtableCount, GlyphCount, BacktrackClassDefinition, BacktrackClassesIncluded, KBTS__ARRAY_LENGTH(BacktrackClassesIncluded));+ kbts__MarkMatrixClassDef(GlyphLookupSubtableMatrix, RunningSubtableIndex, SubtableCount, GlyphCount, InputClassDefinition, InputClassesIncluded, KBTS__ARRAY_LENGTH(InputClassesIncluded));+ kbts__MarkMatrixClassDef(GlyphLookupSubtableMatrix, RunningSubtableIndex, SubtableCount, GlyphCount, LookaheadClassDefinition, LookaheadClassesIncluded, KBTS__ARRAY_LENGTH(LookaheadClassesIncluded));+ } break;++ case 3:+ {+ kbts__chained_sequence_context_3 *Subst = (kbts__chained_sequence_context_3 *)Base;+ kbts__unpacked_chained_sequence_context_3 Unpacked = kbts__UnpackChainedSequenceContext3(Subst, 0);++ Coverage = KBTS__POINTER_OFFSET(kbts__coverage, Subst, Unpacked.InputCoverageOffsets[0]);++ SubtableInfo.MinimumBacktrackPlusOne = KBTS__MIN(SubtableInfo.MinimumBacktrackPlusOne - 1, Unpacked.BacktrackCount) + 1;+ SubtableInfo.MinimumFollowupPlusOne = KBTS__MIN(SubtableInfo.MinimumFollowupPlusOne - 1, Unpacked.InputCount - 1 + Unpacked.LookaheadCount) + 1;++ KBTS__FOR(BacktrackCoverageIndex, 0, Unpacked.BacktrackCount)+ {+ kbts__coverage *SubCoverage = KBTS__POINTER_OFFSET(kbts__coverage, Subst, Unpacked.BacktrackCoverageOffsets[BacktrackCoverageIndex]);+ kbts__MarkMatrixCoverage(GlyphLookupSubtableMatrix, RunningSubtableIndex, SubtableCount, GlyphCount, SubCoverage, 1);+ }++ KBTS__FOR(InputCoverageIndex, 1, Unpacked.InputCount)+ {+ kbts__coverage *SubCoverage = KBTS__POINTER_OFFSET(kbts__coverage, Subst, Unpacked.InputCoverageOffsets[InputCoverageIndex]);+ kbts__MarkMatrixCoverage(GlyphLookupSubtableMatrix, RunningSubtableIndex, SubtableCount, GlyphCount, SubCoverage, 1);+ }+++ KBTS__FOR(LookaheadCoverageIndex, 0, Unpacked.LookaheadCount)+ {+ kbts__coverage *SubCoverage = KBTS__POINTER_OFFSET(kbts__coverage, Subst, Unpacked.LookaheadCoverageOffsets[LookaheadCoverageIndex]);+ kbts__MarkMatrixCoverage(GlyphLookupSubtableMatrix, RunningSubtableIndex, SubtableCount, GlyphCount, SubCoverage, 1);+ }+ } break;+ }+ }+ else if(!InGpos && (LookupType == 8))+ {+ kbts__reverse_chain_substitution *Subst = (kbts__reverse_chain_substitution *)Base;+ kbts__unpacked_reverse_chain_substitution Unpacked = kbts__UnpackReverseChainSubstitution(Subst, 0);+ SubtableInfo.MinimumBacktrackPlusOne = KBTS__MIN(SubtableInfo.MinimumBacktrackPlusOne - 1, Unpacked.BacktrackCount) + 1;+ SubtableInfo.MinimumFollowupPlusOne = KBTS__MIN(SubtableInfo.MinimumFollowupPlusOne - 1, Unpacked.LookaheadCount) + 1;++ KBTS__FOR(BacktrackIndex, 0, Unpacked.BacktrackCount)+ {+ kbts__coverage *SubCoverage = KBTS__POINTER_OFFSET(kbts__coverage, Subst, Unpacked.BacktrackCoverageOffsets[BacktrackIndex]);+ kbts__MarkMatrixCoverage(GlyphLookupSubtableMatrix, RunningSubtableIndex, SubtableCount, GlyphCount, SubCoverage, 1);+ }++ KBTS__FOR(LookaheadIndex, 0, Unpacked.LookaheadCount)+ {+ kbts__coverage *SubCoverage = KBTS__POINTER_OFFSET(kbts__coverage, Subst, Unpacked.LookaheadCoverageOffsets[LookaheadIndex]);+ kbts__MarkMatrixCoverage(GlyphLookupSubtableMatrix, RunningSubtableIndex, SubtableCount, GlyphCount, SubCoverage, 1);+ }+ }++ kbts__MarkMatrixCoverage(GlyphLookupMatrix, RunningLookupIndex, LookupCount, GlyphCount, Coverage, 0);+ kbts__MarkMatrixCoverage(GlyphLookupSubtableMatrix, RunningSubtableIndex, SubtableCount, GlyphCount, Coverage, 1);++ SubtableInfos[RunningSubtableIndex] = SubtableInfo;+ RunningSubtableIndex += 1;+ }++ RunningLookupIndex += 1;+ }+ }+ }+ }++ Header->GposLookupIndexOffset = (kbts_u32)GposLookupIndexOffset;+ Header->GlyphLookupMatrixOffsetFromStartOfFile = KBTS__POINTER_DIFF32(GlyphLookupMatrix, Header);+ Header->GlyphLookupSubtableMatrixOffsetFromStartOfFile = KBTS__POINTER_DIFF32(GlyphLookupSubtableMatrix, Header);+ Header->LookupSubtableIndexOffsetsOffsetFromStartOfFile = KBTS__POINTER_DIFF32(LookupSubtableIndexOffsets, Header);+ Header->SubtableInfosOffsetFromStartOfFile = KBTS__POINTER_DIFF32(SubtableInfos, Header);+ }+ }++ if(Result != KBTS_LOAD_FONT_ERROR_NONE)+ {+ Font->Blob = 0;+ }+ Font->Error = Result;++ return Result;+}++KBTS_EXPORT void kbts_GetFontInfo(kbts_font *Font, kbts_font_info *Info)+{+ KBTS_MEMSET(Info, 0, sizeof(*Info));+ kbts_blob_header *Blob = Font->Blob;++ if(kbts_FontIsValid(Font) && Blob)+ {+ kbts_blob_table *NameTable = &Blob->Tables[KBTS_BLOB_TABLE_ID_NAME];++ if(NameTable->Length)+ {+ kbts__name *Name = KBTS__POINTER_OFFSET(kbts__name, Blob, NameTable->OffsetFromStartOfFile);+ kbts__name_record *Records = KBTS__POINTER_AFTER(kbts__name_record, Name);+ char *StringBase = KBTS__POINTER_OFFSET(char, Name, Name->StringStorageOffset);++ KBTS__FOR(RecordIndex, 0, Name->Count)+ {+ kbts__name_record *Record = &Records[RecordIndex];++ if(!Record->LanguageId)+ {+ kbts_font_info_string_id Id = KBTS_FONT_INFO_STRING_ID_NONE;++ switch(Record->NameId)+ {+ case 0: Id = KBTS_FONT_INFO_STRING_ID_COPYRIGHT; break;+ case 1: Id = KBTS_FONT_INFO_STRING_ID_FAMILY; break;+ case 2: Id = KBTS_FONT_INFO_STRING_ID_SUBFAMILY; break;+ case 3: Id = KBTS_FONT_INFO_STRING_ID_UID; break;+ case 4: Id = KBTS_FONT_INFO_STRING_ID_FULL_NAME; break;+ case 5: Id = KBTS_FONT_INFO_STRING_ID_VERSION; break;+ case 6: Id = KBTS_FONT_INFO_STRING_ID_POSTSCRIPT_NAME; break;+ case 7: Id = KBTS_FONT_INFO_STRING_ID_TRADEMARK; break;+ case 8: Id = KBTS_FONT_INFO_STRING_ID_MANUFACTURER; break;+ case 9: Id = KBTS_FONT_INFO_STRING_ID_DESIGNER; break;+ case 10: Id = KBTS_FONT_INFO_STRING_ID_TYPOGRAPHIC_FAMILY; break;+ case 11: Id = KBTS_FONT_INFO_STRING_ID_TYPOGRAPHIC_SUBFAMILY; break;+ }++ if(Id)+ {+ Info->Strings[Id] = KBTS__POINTER_OFFSET(char, StringBase, Record->StringOffset);+ Info->StringLengths[Id] = Record->Length;+ }+ }+ }++ if(!Info->Strings[KBTS_FONT_INFO_STRING_ID_TYPOGRAPHIC_FAMILY])+ {+ Info->Strings[KBTS_FONT_INFO_STRING_ID_TYPOGRAPHIC_FAMILY] = Info->Strings[KBTS_FONT_INFO_STRING_ID_FAMILY];+ Info->StringLengths[KBTS_FONT_INFO_STRING_ID_TYPOGRAPHIC_FAMILY] = Info->StringLengths[KBTS_FONT_INFO_STRING_ID_FAMILY];+ }++ if(!Info->Strings[KBTS_FONT_INFO_STRING_ID_TYPOGRAPHIC_SUBFAMILY])+ {+ Info->Strings[KBTS_FONT_INFO_STRING_ID_TYPOGRAPHIC_SUBFAMILY] = Info->Strings[KBTS_FONT_INFO_STRING_ID_SUBFAMILY];+ Info->StringLengths[KBTS_FONT_INFO_STRING_ID_TYPOGRAPHIC_SUBFAMILY] = Info->StringLengths[KBTS_FONT_INFO_STRING_ID_SUBFAMILY];+ }+ }++ kbts_blob_table *Os2Table = &Blob->Tables[KBTS_BLOB_TABLE_ID_OS2];++ if(Os2Table->Length)+ {+ kbts__os2 *Os2 = KBTS__POINTER_OFFSET(kbts__os2, Blob, Os2Table->OffsetFromStartOfFile);+ kbts_font_weight Weight = KBTS_FONT_WEIGHT_UNKNOWN;+ kbts_font_width Width = KBTS_FONT_WIDTH_UNKNOWN;+ kbts_font_style_flags StyleFlags = KBTS_FONT_STYLE_FLAG_NONE;++ switch(Os2->WeightClass)+ {+ case 100: Weight = KBTS_FONT_WEIGHT_THIN; break;+ case 200: Weight = KBTS_FONT_WEIGHT_EXTRA_LIGHT; break;+ case 300: Weight = KBTS_FONT_WEIGHT_LIGHT; break;+ case 400: Weight = KBTS_FONT_WEIGHT_NORMAL; break;+ case 500: Weight = KBTS_FONT_WEIGHT_MEDIUM; break;+ case 600: Weight = KBTS_FONT_WEIGHT_SEMI_BOLD; break;+ case 700: Weight = KBTS_FONT_WEIGHT_BOLD; break;+ case 800: Weight = KBTS_FONT_WEIGHT_EXTRA_BOLD; break;+ case 900: Weight = KBTS_FONT_WEIGHT_BLACK; break;+ }++ switch(Os2->WidthClass)+ {+ case 1: Width = KBTS_FONT_WIDTH_ULTRA_CONDENSED; break;+ case 2: Width = KBTS_FONT_WIDTH_EXTRA_CONDENSED; break;+ case 3: Width = KBTS_FONT_WIDTH_CONDENSED; break;+ case 4: Width = KBTS_FONT_WIDTH_SEMI_CONDENSED; break;+ case 5: Width = KBTS_FONT_WIDTH_NORMAL; break;+ case 6: Width = KBTS_FONT_WIDTH_SEMI_EXPANDED; break;+ case 7: Width = KBTS_FONT_WIDTH_EXPANDED; break;+ case 8: Width = KBTS_FONT_WIDTH_EXTRA_EXPANDED; break;+ case 9: Width = KBTS_FONT_WIDTH_ULTRA_EXPANDED; break;+ }++ if(Os2->Selection & (KBTS__OS2_SELECTION_FLAG_ITALIC | KBTS__OS2_SELECTION_FLAG_OBLIQUE))+ {+ StyleFlags |= KBTS_FONT_STYLE_FLAG_ITALIC;+ }+ if(Os2->Selection & KBTS__OS2_SELECTION_FLAG_BOLD)+ {+ StyleFlags |= KBTS_FONT_STYLE_FLAG_BOLD;+ }+ if(Os2->Selection & KBTS__OS2_SELECTION_FLAG_REGULAR)+ {+ StyleFlags |= KBTS_FONT_STYLE_FLAG_REGULAR;+ }++ Info->Weight = Weight;+ Info->Width = Width;+ Info->StyleFlags = StyleFlags;+ }+ }+}++KBTS_EXPORT kbts_font kbts_FontFromMemory(void *FileData, int FileSize, int FontIndex, kbts_allocator_function *Allocator, void *AllocatorData)+{+ kbts_font Result = KBTS__ZERO;++ if(!Allocator)+ {+ Allocator = kbts__DefaultAllocator;+ }++ if(FileData && (FileSize > 0))+ {+ kbts_load_font_state LoadFontState = KBTS__ZERO;+ int ScratchSize, OutputSize;+ kbts_load_font_error Error = kbts_LoadFont(&Result, &LoadFontState, FileData, (int)FileSize, FontIndex, &ScratchSize, &OutputSize);++ if(Error == KBTS_LOAD_FONT_ERROR_NEED_TO_CREATE_BLOB)+ {+ void *ScratchMemory = kbts__AllocatorAllocate(Allocator, AllocatorData, (kbts_un)ScratchSize);+ void *OutputMemory = kbts__AllocatorAllocate(Allocator, AllocatorData, (kbts_un)OutputSize);++ kbts_PlaceBlob(&Result, &LoadFontState, ScratchMemory, OutputMemory);++ kbts__AllocatorFree(Allocator, AllocatorData, ScratchMemory);++ Result.Allocator = Allocator;+ Result.AllocatorData = AllocatorData;+ }+ }++ return Result;+}++#ifndef KB_TEXT_SHAPE_NO_CRT++KBTS_EXPORT kbts_font kbts_FontFromFile(const char *FileName, int FontIndex, kbts_allocator_function *Allocator, void *AllocatorData, void **FileData, int *FileSize_)+{+ kbts_font Result = KBTS__ZERO;++ if(!Allocator)+ {+ Allocator = kbts__DefaultAllocator;+ }++ FILE *File;+# ifndef _MSC_VER+ File = fopen(FileName, "rb");+# else+ fopen_s(&File, FileName, "rb");+# endif++ if(File)+ {+ fseek(File, 0, SEEK_END);+ long FileSize = ftell(File);+ fseek(File, 0, SEEK_SET);++ if(FileSize > 0)+ {+ void *Data = kbts__AllocatorAllocate(Allocator, AllocatorData, (kbts_un)FileSize);++ if(Data)+ {+ kbts_un Ok = fread(Data, (kbts_un)FileSize, 1, File);++ if(Ok)+ {+ Result = kbts_FontFromMemory(Data, (int)FileSize, FontIndex, Allocator, AllocatorData);++ if(!Result.Error)+ {++ if(FileData)+ {+ *FileData = Data;+ }+ else+ {+ kbts__AllocatorFree(Allocator, AllocatorData, Data);+ }++ if(FileSize_)+ {+ *FileSize_ = (int)FileSize;+ }+ }+ }+ else+ {+ Result.Error = KBTS_LOAD_FONT_ERROR_READ_ERROR;+ }+ }+ else+ {+ Result.Error = KBTS_LOAD_FONT_ERROR_OUT_OF_MEMORY;+ }+ }++ fclose(File);+ }+ else+ {+ Result.Error = KBTS_LOAD_FONT_ERROR_COULD_NOT_OPEN_FILE;+ }++ return Result;+}++#endif++KBTS_EXPORT void kbts_FreeFont(kbts_font *Font)+{+ if(Font->Blob && Font->Allocator)+ {+ kbts__AllocatorFree(Font->Allocator, Font->AllocatorData, Font->Blob);+ }+}++static void kbts__DoBreak(kbts_break_state *State, kbts_s32 Position, kbts_u8 Flags, kbts_direction Direction, kbts_direction ParagraphDirection, kbts_script Script)+{+ kbts_u32 BreakPosition = State->CurrentPosition + (kbts_u32)Position;+ if(Flags &&+ (BreakPosition <= State->CurrentPosition))+ {+ kbts_break Break = KBTS__ZERO;+ Break.Position = (int)BreakPosition;+ Break.Flags = Flags;+ Break.Direction = Direction;+ Break.ParagraphDirection = ParagraphDirection;+ Break.Script = Script;++ if((Flags & KBTS_BREAK_FLAG_SCRIPT) &&+ (State->LastScriptBreakScript))+ {+ kbts_un LastScriptBreakPosition = State->LastScriptBreakPosition;+ kbts_u8 LastScriptBreakScript = State->LastScriptBreakScript;++ // Resolve bracket scripts here.+ // The only span we can fully resolve is the _previous_ script, but we don't+ // know when it starts, so we might as well tag all of the brackets we have stored so far.+ for(kbts_un BracketIndex = State->BracketCount;+ BracketIndex;+ --BracketIndex)+ {+ kbts_bracket *Bracket = &State->Brackets[BracketIndex - 1];++ if(Bracket->Position >= BreakPosition)+ {+ Bracket->Script = (kbts_u8)Script;+ }+ else if(Bracket->Position >= LastScriptBreakPosition)+ {+ Bracket->Script = LastScriptBreakScript;+ }+ else+ {+ break;+ }+ }++ State->LastScriptBreakPosition = BreakPosition;+ State->LastScriptBreakScript = (kbts_u8)Script;+ }++ if((Flags & KBTS_BREAK_FLAG_DIRECTION) &&+ (State->LastDirectionBreakDirection))+ {+ kbts_un LastDirectionBreakPosition = State->LastDirectionBreakPosition;+ kbts_u8 LastDirectionBreakDirection = State->LastDirectionBreakDirection;++ for(kbts_un BracketIndex = State->BracketCount;+ BracketIndex;+ --BracketIndex)+ {+ kbts_bracket *Bracket = &State->Brackets[BracketIndex - 1];++ if(Bracket->Position >= BreakPosition)+ {+ Bracket->Direction = (kbts_u8)Direction;+ }+ else if(Bracket->Position >= LastDirectionBreakPosition)+ {+ Bracket->Direction = LastDirectionBreakDirection;+ }+ else+ {+ break;+ }+ }++ State->LastDirectionBreakPosition = BreakPosition;+ State->LastDirectionBreakDirection = (kbts_u8)Direction;+ }++ int Matched = 0;+ KBTS__FOR(BreakIndex, 0, State->BreakCount)+ {+ kbts_break *Existing = &State->Breaks[BreakIndex];++ if(Existing->Position == Break.Position)+ {+ Existing->Flags |= Break.Flags;++ if(Break.Flags & KBTS_BREAK_FLAG_DIRECTION)+ {+ Existing->Direction = Break.Direction;+ }++ if(Break.Flags & KBTS_BREAK_FLAG_PARAGRAPH_DIRECTION)+ {+ Existing->ParagraphDirection = Break.ParagraphDirection;+ }++ if(Break.Flags & KBTS_BREAK_FLAG_SCRIPT)+ {+ Existing->Script = Break.Script;+ }++ Matched = 1;++ break;+ }+ else if(Existing->Position < Break.Position)+ {+ // We order breaks in backwards order here, because we want to simply pop them off the top in Break().+ kbts_break Swap = *Existing;+ *Existing = Break;+ Break = Swap;+ }+ else if((Break.Flags & KBTS_BREAK_FLAG_PARAGRAPH_DIRECTION) &&+ (Existing->Flags & KBTS_BREAK_FLAG_DIRECTION) &&+ !Existing->Direction)+ {+ // Short-circuit coerce neutral blocks to the paragraph direction.+ Existing->Direction = Break.ParagraphDirection;+ }+ }++ State->Breaks[State->BreakCount] = Break;+ State->BreakCount += !Matched;+ }+}++// The line break state is a 4-character history. Each character is a bags of 12 bits (padded to 16 bits).+// Each character specifies allowed and required breaks on 6 levels of priority.+// A required break implies an allowed break.+// A priority N break implies priority 0..N-1 breaks.+enum {+ KBTS__LINE_BREAK_ALLOWED0 = 1,+ KBTS__LINE_BREAK_ALLOWED1 = 3,+ KBTS__LINE_BREAK_ALLOWED2 = 7,+ KBTS__LINE_BREAK_ALLOWED3 = 0xF,+ KBTS__LINE_BREAK_ALLOWED4 = 0x1F,+ KBTS__LINE_BREAK_ALLOWED5 = 0x3F,+ KBTS__LINE_BREAK_REQUIRED0 = (1 << 6) | KBTS__LINE_BREAK_ALLOWED0,+ KBTS__LINE_BREAK_REQUIRED1 = (3 << 6) | KBTS__LINE_BREAK_ALLOWED1,+ KBTS__LINE_BREAK_REQUIRED2 = (7 << 6) | KBTS__LINE_BREAK_ALLOWED2,+ KBTS__LINE_BREAK_REQUIRED3 = (0xF << 6) | KBTS__LINE_BREAK_ALLOWED3,+ KBTS__LINE_BREAK_REQUIRED4 = (0x1F << 6) | KBTS__LINE_BREAK_ALLOWED4,+ KBTS__LINE_BREAK_REQUIRED5 = (0x3F << 6) | KBTS__LINE_BREAK_ALLOWED5,+ KBTS__LINE_BREAK_REQUIRED_MASK = 0x3F << 6,+ KBTS__LINE_BREAK_ALLOWED_MASK = 0x3F,+ KBTS__LINE_BREAK_MASK = KBTS__LINE_BREAK_REQUIRED_MASK | KBTS__LINE_BREAK_ALLOWED_MASK,+};++static void kbts__DoLineBreak(kbts_break_state *State, int Position, kbts_u64 EffectiveLineBreaks)+{+ if(EffectiveLineBreaks & KBTS__LINE_BREAK_MASK)+ {+ kbts_u8 Flags = 0;++ if(EffectiveLineBreaks & KBTS__LINE_BREAK_ALLOWED_MASK)+ {+ Flags |= KBTS_BREAK_FLAG_LINE_SOFT;+ }++ if(EffectiveLineBreaks & KBTS__LINE_BREAK_REQUIRED_MASK)+ {+ Flags |= KBTS_BREAK_FLAG_LINE_HARD;+ }++ kbts__DoBreak(State, Position, Flags, 0, 0, 0);+ }+}++static void kbts__BreakStateStartParagraph(kbts_break_state *State)+{+ kbts_direction ParagraphDirection = State->UserParagraphDirection;+ // At the beginning of a paragraph, we want to pretend like start-of-text is an actual character+ // with bidirectional data that depends on its direction.+ kbts_u32 StartOfTextBidirectionalClass = KBTS_UNICODE_BIDIRECTIONAL_CLASS_NI;+ kbts_u32 Flags = 0;++ if(ParagraphDirection == KBTS_DIRECTION_LTR)+ {+ StartOfTextBidirectionalClass = KBTS_UNICODE_BIDIRECTIONAL_CLASS_L;+ }+ else if(ParagraphDirection == KBTS_DIRECTION_RTL)+ {+ Flags = KBTS_BREAK_STATE_FLAG_SAW_R_AFTER_L;+ StartOfTextBidirectionalClass = KBTS_UNICODE_BIDIRECTIONAL_CLASS_R;+ }++ State->ParagraphDirection = (kbts_u8)ParagraphDirection;+ State->BidirectionalClass1 = (kbts_u8)StartOfTextBidirectionalClass;+ State->Flags = Flags;+}++typedef kbts_u32 kbts__break_flush_flags;+enum kbts__break_flush_flags_enum+{+ KBTS__BREAK_FLUSH_FLAG_NONE,+ KBTS__BREAK_FLUSH_FLAG_SCRIPT = (1 << 0),+ KBTS__BREAK_FLUSH_FLAG_DIRECTION_2 = (1 << 1),+ KBTS__BREAK_FLUSH_FLAG_DIRECTION_1 = (1 << 2),+ KBTS__BREAK_FLUSH_FLAG_DIRECTION_PARAGRAPH = (1 << 3),+};++static void kbts__FlushDirection(kbts_break_state *State, kbts_direction *LastDirection, kbts_unicode_bidirectional_class BidirectionalClass, kbts_s16 PositionOffset)+{+ // @Incomplete: ET+ EN -> EN+ EN+ kbts_break_flags BreakFlags = 0;+ kbts_direction Direction = KBTS_DIRECTION_DONT_KNOW;++ switch(BidirectionalClass)+ {+ // @Incomplete: Surely, there are other edge cases we could handle here.+ case KBTS_UNICODE_BIDIRECTIONAL_CLASS_L:+ BreakFlags = KBTS_BREAK_FLAG_DIRECTION | KBTS_BREAK_FLAG_PARAGRAPH_DIRECTION;+ Direction = KBTS_DIRECTION_LTR;+ break;++ case KBTS_UNICODE_BIDIRECTIONAL_CLASS_R:+ BreakFlags = KBTS_BREAK_FLAG_DIRECTION | KBTS_BREAK_FLAG_PARAGRAPH_DIRECTION;+ Direction = KBTS_DIRECTION_RTL;+ break;++ case KBTS_UNICODE_BIDIRECTIONAL_CLASS_AN:+ case KBTS_UNICODE_BIDIRECTIONAL_CLASS_EN:+ // Digits are weak LTR, i.e. they do not influence the paragraph direction.+ BreakFlags = KBTS_BREAK_FLAG_DIRECTION;+ Direction = KBTS_DIRECTION_LTR;+ break;++ case KBTS_UNICODE_BIDIRECTIONAL_CLASS_NI:+ // We've already checked the ParagraphDirection earlier, when coercing neutrals to L or R.+ // If a neutral shows up here, it means that we did not find any way to resolve it to either direction.+ // In this case, neutrals get the unresolved embedding direction.+ BreakFlags = KBTS_BREAK_FLAG_DIRECTION;+ break;+ }++ if((BreakFlags & KBTS_BREAK_FLAG_DIRECTION) &&+ (Direction != *LastDirection))+ {+ *LastDirection = Direction;+ kbts__DoBreak(State, PositionOffset, KBTS_BREAK_FLAG_DIRECTION, Direction, 0, 0);+ }++ if((BreakFlags & KBTS_BREAK_FLAG_PARAGRAPH_DIRECTION) &&+ !State->ParagraphDirection)+ {+ kbts_s32 StartOfParagraphOffset = (kbts_s16)(State->ParagraphStartPosition - State->CurrentPosition);+ kbts__DoBreak(State, StartOfParagraphOffset, KBTS_BREAK_FLAG_PARAGRAPH_DIRECTION, 0, Direction, 0);+ State->ParagraphDirection = (kbts_u8)Direction;+ }+}++static void kbts__BreakAddCodepoint(kbts_break_state *State, kbts_u32 Codepoint, kbts_u32 PositionIncrement, int MaybeEndOfText)+{+ // In these macros, and in FlagState, and in the way we buffer our state in general,+ // index 0 means _after_ the codepoint currently being added,+ // index 1 means _before_ the codepoint currently being added.+#define KBTS_BREAK(Flags, Position) do {FlagState |= ((Flags) << (8 * (Position)));} while(0)+#define KBTS_BREAK2(Flags, Position0, Position1) do {FlagState |= ((Flags) << (8 * (Position0))) | ((Flags) << (8 * (Position1)));} while(0)++ kbts_unicode_bidirectional_class BidirectionalClass = kbts__GetUnicodeBidirectionalClass(Codepoint);+ kbts_u8 UnicodeFlags = kbts__GetUnicodeFlags(Codepoint);+ kbts_u32 MatchingBracket = kbts__GetUnicodeMirrorCodepoint(Codepoint);+ kbts_u8 GraphemeBreakClass = kbts__GetUnicodeGraphemeBreakClass(Codepoint);+ kbts_u8 LineBreakClass = kbts__GetUnicodeLineBreakClass(Codepoint);+ kbts_u8 WordBreakClass = kbts__GetUnicodeWordBreakClass(Codepoint);+ kbts_u16 CodepointScriptExtension = kbts__GetUnicodeScriptExtension(Codepoint);+ kbts_u32 CodepointScriptCount = (kbts_u32)kbts__ScriptExtensionCount(CodepointScriptExtension);+ kbts_u32 CodepointScriptOffset = (kbts_u32)kbts__ScriptExtensionOffset(CodepointScriptExtension);+ kbts_u8 *CodepointScripts = &kbts__ScriptExtensions[CodepointScriptOffset];+ kbts_u32 FlagState = State->FlagState << 8;+ kbts_u8 LastLineBreakClass = State->LastLineBreakClass;+ // Super secret cheat code for signaling end-of-text+ int EndOfText = (Codepoint == 3) && MaybeEndOfText;+ int StartOfText = !(State->Flags & KBTS_BREAK_STATE_FLAG_STARTED);+ kbts_u32 LineBreakHistory = State->LineBreakHistory;+ kbts_u32 WordBreakHistory = State->WordBreakHistory;+ kbts_u8 LastWordBreakClass = State->LastWordBreakClass;+ kbts_s16 WordBreak2PositionOffset = State->WordBreak2PositionOffset;+ kbts_u8 LastWordBreakClassIncludingIgnored = State->LastWordBreakClassIncludingIgnored;+ kbts_s16 PositionOffset2 = State->PositionOffset2;+ kbts_s16 PositionOffset3 = State->PositionOffset3;+ kbts_u32 Flags = State->Flags;+ kbts_direction LastDirection = State->LastDirection;+ kbts_u8 *ScriptSet = State->ScriptSet;+ kbts_s16 ScriptPositionOffset = State->ScriptPositionOffset;+ kbts_u32 ScriptCount = State->ScriptCount;+ kbts_u32 ScriptCountAtBeginningOfUpdate = ScriptCount;+ kbts_u8 BreakScript = ScriptSet[0];+ kbts__break_flush_flags FlushFlags = 0;+ kbts_s16 Bidirectional1PositionOffset = State->Bidirectional1PositionOffset;+ kbts_s16 Bidirectional2PositionOffset = State->Bidirectional2PositionOffset;+ kbts_u8 Bidirectional2 = State->BidirectionalClass2;+ kbts_u8 Bidirectional1 = State->BidirectionalClass1;++ if(StartOfText)+ {+ LineBreakHistory = LastLineBreakClass = KBTS_LINE_BREAK_CLASS_SOT;+ WordBreakHistory = LastWordBreakClass = KBTS_WORD_BREAK_CLASS_SOT;+ }++ // Bracket pairing overrides default directions/scripts.+ if((UnicodeFlags & KBTS_UNICODE_FLAG_MIRRORED) == KBTS_UNICODE_FLAG_OPEN_BRACKET)+ {+ if(State->BracketCount < KBTS__ARRAY_LENGTH(State->Brackets))+ {+ kbts_bracket *Bracket = &State->Brackets[State->BracketCount++];++ // @Incomplete: Canonicalize the bracket.+ Bracket->Codepoint = Codepoint;+ Bracket->Position = State->CurrentPosition;++ // Unfortunately, because our script/direction breaks are arbitrary lookback now,+ // we have to wait until DoBreak() to resolve these.+ Bracket->Direction = KBTS_DIRECTION_DONT_KNOW;+ Bracket->Script = KBTS_SCRIPT_DONT_KNOW;++ if(ScriptCount)+ {+ Bracket->Script = ScriptSet[0];+ }++ State->Flags |= KBTS_BREAK_STATE_FLAG_LAST_WAS_BRACKET;+ }+ }+ else if((UnicodeFlags & KBTS_UNICODE_FLAG_MIRRORED) == KBTS_UNICODE_FLAG_CLOSE_BRACKET)+ {+ if(State->BracketCount)+ {+ kbts_un FoundBracketIndex = 0;+ kbts_bracket *FoundBracket = 0;++ // @Incomplete: Canonicalize the bracket.+ KBTS__FOR(BracketIndex, 0, State->BracketCount)+ {+ kbts_bracket *Bracket = &State->Brackets[State->BracketCount - 1 - BracketIndex];++ if(Bracket->Codepoint == MatchingBracket)+ {+ FoundBracket = Bracket;+ FoundBracketIndex = State->BracketCount - 1 - BracketIndex;++ break;+ }+ }++ if(FoundBracket)+ {+ // In case the bracket hasn't been resolved yet, take the current values.+ kbts_u8 BracketScript = FoundBracket->Script;+ kbts_u8 BracketDirection = FoundBracket->Direction;++ if(!BracketScript && ScriptCount)+ {+ BracketScript = ScriptSet[0];+ }++ if(!BracketDirection)+ {+ BracketDirection = (kbts_u8)LastDirection;+ }++ if(BracketDirection == KBTS_DIRECTION_LTR)+ {+ BidirectionalClass = KBTS_UNICODE_BIDIRECTIONAL_CLASS_L;+ }+ else if(BracketDirection == KBTS_DIRECTION_RTL)+ {+ BidirectionalClass = KBTS_UNICODE_BIDIRECTIONAL_CLASS_R;+ }++ BidirectionalClass = FoundBracket->Direction;+ CodepointScriptCount = 1;+ CodepointScriptOffset = BracketScript;++ State->BracketCount = (kbts_u32)FoundBracketIndex;+ }+ }+ }++ // Script breaking.+ if(EndOfText)+ {+ FlushFlags |= KBTS__BREAK_FLUSH_FLAG_SCRIPT;+ }++ if(CodepointScriptCount < 2)+ {+ // We special case this entire path because, supposedly, this is the common case.+ kbts_u8 CodepointScript = (kbts_u8)CodepointScriptOffset;++ if((CodepointScript == KBTS_SCRIPT_DONT_KNOW) ||+ (CodepointScript == KBTS_SCRIPT_DEFAULT) ||+ (CodepointScript == KBTS_SCRIPT_DEFAULT2))+ {+ // Nothing to do.+ }+ else+ {+ kbts_u32 ScriptSetMatch = 0;+ KBTS__FOR(ScriptIndex, 0, ScriptCount)+ {+ ScriptSetMatch |= (ScriptSet[ScriptIndex] == CodepointScript);+ }++ if(!ScriptSetMatch)+ {+ FlushFlags |= KBTS__BREAK_FLUSH_FLAG_SCRIPT;+ }++ ScriptCount = 1;+ ScriptSet[0] = CodepointScript;+ }+ }+ else+ {+ // Refine the script set.+ kbts_un NewScriptCount = 0;++ {+ kbts_un CodepointScriptIndex = 0;+ kbts_un ScriptIndex = 0;++ while((ScriptIndex < ScriptCount) &&+ (CodepointScriptIndex < CodepointScriptCount))+ {+ kbts_u8 CodepointScript = CodepointScripts[CodepointScriptIndex];+ kbts_u8 Script = ScriptSet[ScriptIndex];++ if(CodepointScript < Script)+ {+ CodepointScriptIndex += 1;+ }+ else if(Script < CodepointScript)+ {+ ScriptIndex += 1;+ }+ else+ {+ ScriptSet[NewScriptCount++] = Script;++ CodepointScriptIndex += 1;+ ScriptIndex += 1;+ }+ }+ }++ if(!NewScriptCount)+ {+ FlushFlags |= KBTS__BREAK_FLUSH_FLAG_SCRIPT;++ KBTS__FOR(CodepointScriptIndex, 0, CodepointScriptCount)+ {+ ScriptSet[CodepointScriptIndex] = CodepointScripts[CodepointScriptIndex];+ }+ ScriptCount = (kbts_u32)CodepointScriptCount;+ }+ else+ {+ ScriptCount = (kbts_u32)NewScriptCount;+ }+ }++ // Direction breaking.+ if(EndOfText)+ {+ BidirectionalClass = KBTS_UNICODE_BIDIRECTIONAL_CLASS_NI;+ }++ if(BidirectionalClass != KBTS_UNICODE_BIDIRECTIONAL_CLASS_BN) // Formatting characters should be ignored.+ {+ switch(BidirectionalClass)+ {+ case KBTS_UNICODE_BIDIRECTIONAL_CLASS_NSM: BidirectionalClass = Bidirectional1; break;++ case KBTS_UNICODE_BIDIRECTIONAL_CLASS_L:+ Flags &= ~(KBTS_BREAK_STATE_FLAG_SAW_R_AFTER_L | KBTS_BREAK_STATE_FLAG_SAW_AL_AFTER_LR);+ break;++ case KBTS_UNICODE_BIDIRECTIONAL_CLASS_R:+ Flags |= KBTS_BREAK_STATE_FLAG_SAW_R_AFTER_L;+ Flags &= ~KBTS_BREAK_STATE_FLAG_SAW_AL_AFTER_LR;+ break;++ case KBTS_UNICODE_BIDIRECTIONAL_CLASS_AL:+ // Rule W3 occurs before W7, so we treat AL as R for the purposes of rule W7.+ Flags |= (KBTS_BREAK_STATE_FLAG_SAW_AL_AFTER_LR | KBTS_BREAK_STATE_FLAG_SAW_R_AFTER_L);+ BidirectionalClass = KBTS_UNICODE_BIDIRECTIONAL_CLASS_R;+ break;++ case KBTS_UNICODE_BIDIRECTIONAL_CLASS_EN:+ if(Flags & KBTS_BREAK_STATE_FLAG_SAW_AL_AFTER_LR)+ {+ BidirectionalClass = KBTS_UNICODE_BIDIRECTIONAL_CLASS_AN;+ goto CaseAn;+ }+ if((Bidirectional2 == KBTS_UNICODE_BIDIRECTIONAL_CLASS_EN) &&+ ((Bidirectional1 == KBTS_UNICODE_BIDIRECTIONAL_CLASS_ES) ||+ (Bidirectional1 == KBTS_UNICODE_BIDIRECTIONAL_CLASS_CS)))+ {+ Bidirectional1 = KBTS_UNICODE_BIDIRECTIONAL_CLASS_EN;+ }++ // We test State->ParagraphDirection here because we do not want+ // digits to coerce to L when the paragrpah direction is unknown.+ // It might be cleaner to explicitly store the last strong direction seen,+ // with DONT_KNOW as an option.+ // @Cleanup+ if(State->ParagraphDirection &&+ !(Flags & KBTS_BREAK_STATE_FLAG_SAW_R_AFTER_L))+ {+ BidirectionalClass = KBTS_UNICODE_BIDIRECTIONAL_CLASS_L;+ }+ break;+ case KBTS_UNICODE_BIDIRECTIONAL_CLASS_AN:+ CaseAn:;+ if((Bidirectional2 == KBTS_UNICODE_BIDIRECTIONAL_CLASS_AN) &&+ (Bidirectional1 == KBTS_UNICODE_BIDIRECTIONAL_CLASS_CS))+ {+ Bidirectional1 = KBTS_UNICODE_BIDIRECTIONAL_CLASS_AN;+ }+ break;+ case KBTS_UNICODE_BIDIRECTIONAL_CLASS_ET:+ if(Bidirectional1 == KBTS_UNICODE_BIDIRECTIONAL_CLASS_EN)+ {+ BidirectionalClass = KBTS_UNICODE_BIDIRECTIONAL_CLASS_EN;+ }+ break;+ }++ // This rule has a lower priority than AN CS AN -> AN AN AN, so we have to wait until slot 1 to apply it.+ if(KBTS__IN_SET(Bidirectional1, KBTS__SET32((KBTS_UNICODE_BIDIRECTIONAL_CLASS_ET)+ (KBTS_UNICODE_BIDIRECTIONAL_CLASS_ES)+ (KBTS_UNICODE_BIDIRECTIONAL_CLASS_CS))))+ {+ Bidirectional1 = KBTS_UNICODE_BIDIRECTIONAL_CLASS_NI;+ }++ if(Bidirectional1 == KBTS_UNICODE_BIDIRECTIONAL_CLASS_NI)+ {+ if(KBTS__IN_SET(BidirectionalClass, KBTS__SET32((KBTS_UNICODE_BIDIRECTIONAL_CLASS_NI)+ (KBTS_UNICODE_BIDIRECTIONAL_CLASS_ET)+ (KBTS_UNICODE_BIDIRECTIONAL_CLASS_ES)+ (KBTS_UNICODE_BIDIRECTIONAL_CLASS_CS))))+ {+ // All of these input classes end up resolving to NI later on anyway if they are preceded by NI.+ // We are in a situation where:+ // - We have an NI in slot 1+ // - The direction in slot 0 will eventually resolve to NI due to the NI in slot 1+ // - Storing multiple NIs in our shift buffer is redundant, because no rule necessitates multiple NIs+ // - NIs don't interact with anything, except that they resolve when surrounded by strong characters+ // - NIs are resolved in groups. As per the Unicode specification:+ // N1. A sequence of NIs takes the direction of the surrounding strong text if the text on both+ // sides has the same direction.+ // This means we can merge the current bidirectional class with the preceding NI, bump the offset,+ // and it just works.+ goto SkipDirectionBreak;+ }+ else if(((Bidirectional2 == KBTS_UNICODE_BIDIRECTIONAL_CLASS_R) ||+ (BidirectionalClass == KBTS_UNICODE_BIDIRECTIONAL_CLASS_R)) &&+ KBTS__IN_SET(Bidirectional2, KBTS__SET32((KBTS_UNICODE_BIDIRECTIONAL_CLASS_R)+ (KBTS_UNICODE_BIDIRECTIONAL_CLASS_AN)+ (KBTS_UNICODE_BIDIRECTIONAL_CLASS_EN))) &&+ KBTS__IN_SET(BidirectionalClass, KBTS__SET32((KBTS_UNICODE_BIDIRECTIONAL_CLASS_R)+ (KBTS_UNICODE_BIDIRECTIONAL_CLASS_AN)+ (KBTS_UNICODE_BIDIRECTIONAL_CLASS_EN))))+ {+ // Note that the way we resolve digits is different from the way the Unicode standard specifies it.+ // This is because the standard assumes the paragraph direction is always known, whereas in our case it isn't.+ // We want neutral surrounded by uncoerced digits to resolve to the paragraph direction, which may be DONT_KNOW.+ Bidirectional1 = KBTS_UNICODE_BIDIRECTIONAL_CLASS_R;+ }+ else if(((Bidirectional2 == KBTS_UNICODE_BIDIRECTIONAL_CLASS_L) ||+ (BidirectionalClass == KBTS_UNICODE_BIDIRECTIONAL_CLASS_L)) &&+ KBTS__IN_SET(Bidirectional2, KBTS__SET32((KBTS_UNICODE_BIDIRECTIONAL_CLASS_L)+ (KBTS_UNICODE_BIDIRECTIONAL_CLASS_AN)+ (KBTS_UNICODE_BIDIRECTIONAL_CLASS_EN))) &&+ KBTS__IN_SET(BidirectionalClass, KBTS__SET32((KBTS_UNICODE_BIDIRECTIONAL_CLASS_L)+ (KBTS_UNICODE_BIDIRECTIONAL_CLASS_AN)+ (KBTS_UNICODE_BIDIRECTIONAL_CLASS_EN))))+ {+ Bidirectional1 = KBTS_UNICODE_BIDIRECTIONAL_CLASS_L;+ }+ else+ {+ if (State->ParagraphDirection == KBTS_DIRECTION_LTR) Bidirectional1 = KBTS_UNICODE_BIDIRECTIONAL_CLASS_L;+ else if(State->ParagraphDirection == KBTS_DIRECTION_RTL) Bidirectional1 = KBTS_UNICODE_BIDIRECTIONAL_CLASS_R;+ }+ }++ FlushFlags |= KBTS__BREAK_FLUSH_FLAG_DIRECTION_2;+ if(EndOfText)+ {+ FlushFlags |= KBTS__BREAK_FLUSH_FLAG_DIRECTION_1;+ }+ }+ else+ {+ SkipDirectionBreak:;+ State->Bidirectional2PositionOffset -= (kbts_s16)PositionIncrement;+ State->Bidirectional1PositionOffset -= (kbts_s16)PositionIncrement;+ }++ { // Grapheme breaking.+ if(EndOfText && !StartOfText)+ {+ KBTS_BREAK(KBTS_BREAK_FLAG_GRAPHEME, 1);+ State->GraphemeBreakState = KBTS_GRAPHEME_BREAK_STATE_START;+ }+ else+ {+ kbts_u8 GraphemeBreakState = kbts_GraphemeBreakTransition[GraphemeBreakClass][State->GraphemeBreakState];+ switch(GraphemeBreakState)+ {+ case KBTS_GRAPHEME_BREAK_STATE_b01: KBTS_BREAK2(KBTS_BREAK_FLAG_GRAPHEME, 1, 0); GraphemeBreakState = KBTS_GRAPHEME_BREAK_STATE_START; break;+ case KBTS_GRAPHEME_BREAK_STATE_b0: KBTS_BREAK(KBTS_BREAK_FLAG_GRAPHEME, 0); GraphemeBreakState = KBTS_GRAPHEME_BREAK_STATE_START; break;++ case KBTS_GRAPHEME_BREAK_STATE_b1:+ case KBTS_GRAPHEME_BREAK_STATE_b1toCR:+ case KBTS_GRAPHEME_BREAK_STATE_b1toL:+ case KBTS_GRAPHEME_BREAK_STATE_b1toLVxV:+ case KBTS_GRAPHEME_BREAK_STATE_b1toLVTxT:+ case KBTS_GRAPHEME_BREAK_STATE_b1toIndicConsonantxIndicLinker:+ case KBTS_GRAPHEME_BREAK_STATE_PADDING0: // Padding values are just here to help the compiler.+ case KBTS_GRAPHEME_BREAK_STATE_PADDING1:+ case KBTS_GRAPHEME_BREAK_STATE_b1toExtendedPictographic:+ case KBTS_GRAPHEME_BREAK_STATE_PADDING2:+ case KBTS_GRAPHEME_BREAK_STATE_PADDING3:+ case KBTS_GRAPHEME_BREAK_STATE_b1toRI:+ case KBTS_GRAPHEME_BREAK_STATE_b1toSKIP:+ KBTS_BREAK(KBTS_BREAK_FLAG_GRAPHEME, 1);+ GraphemeBreakState -= KBTS_GRAPHEME_BREAK_STATE_b1;+ }++ State->GraphemeBreakState = GraphemeBreakState;+ }+ }++ // Word breaks.+ // We buffer 3 characters for word breaks.+ // Each character gets 3 bits (padded to 4) representing 3 levels of priority.+ #define KBTS_WORD_BREAK_BITS(Priority, Position) (((1 << ((Priority) + 1)) - 1) << ((Position) * 4))+ #define KBTS_C2(A, B) case (KBTS_WORD_BREAK_CLASS_##A << 8) | (KBTS_WORD_BREAK_CLASS_##B)+ #define KBTS_C3(A, B, C) case (KBTS_WORD_BREAK_CLASS_##A << 16) | (KBTS_WORD_BREAK_CLASS_##B << 8) | (KBTS_WORD_BREAK_CLASS_##C)++ // Ignore [EX FO ZWJ] after ^[_sot_ CR LF NL].+ // @Cleanup: This is the only time we explicitly use EX and FO. They can be merged.+ if(KBTS__IN_SET(WordBreakClass, KBTS__SET32((KBTS_WORD_BREAK_CLASS_EX)(KBTS_WORD_BREAK_CLASS_FO)(KBTS_WORD_BREAK_CLASS_ZWJ))) &&+ !KBTS__IN_SET(LastWordBreakClass, KBTS__SET32((KBTS_WORD_BREAK_CLASS_SOT)(KBTS_WORD_BREAK_CLASS_CR)(KBTS_WORD_BREAK_CLASS_LF)(KBTS_WORD_BREAK_CLASS_NL))))+ {+ WordBreak2PositionOffset -= (kbts_s16)PositionIncrement;+ State->WordBreak2PositionOffset = WordBreak2PositionOffset;+ }+ else+ {+ kbts_u32 WordBreaks = State->WordBreaks << 4;+ kbts_u32 WordUnbreaks = State->WordUnbreaks << 4;+ WordBreakHistory = (WordBreakHistory << 8) | WordBreakClass;++ WordBreaks |= KBTS_WORD_BREAK_BITS(0, 1) | KBTS_WORD_BREAK_BITS(0, 0);+ if(StartOfText)+ {+ WordBreaks |= KBTS_WORD_BREAK_BITS(2, 1);+ }++ if(KBTS__IN_SET(WordBreakClass, KBTS__SET32((KBTS_WORD_BREAK_CLASS_CR)(KBTS_WORD_BREAK_CLASS_LF)(KBTS_WORD_BREAK_CLASS_NL))))+ {+ WordBreaks |= KBTS_WORD_BREAK_BITS(1, 1) | KBTS_WORD_BREAK_BITS(1, 0);+ }+ else if(KBTS__IN_SET(WordBreakClass, KBTS__SET32((KBTS_WORD_BREAK_CLASS_Oep)(KBTS_WORD_BREAK_CLASS_ALep))))+ {+ // ZWJ x {Extended_Pictographic}+ if(LastWordBreakClassIncludingIgnored == KBTS_WORD_BREAK_CLASS_ZWJ)+ {+ WordUnbreaks |= KBTS_WORD_BREAK_BITS(0, 1);+ }+ }++ switch(WordBreakHistory & 0xFFFF)+ {+ KBTS_C2(CR, LF): WordUnbreaks |= KBTS_WORD_BREAK_BITS(1, 1); break;++ KBTS_C2(WSS, WSS):+ // WSS x WSS is a special rule, because it is supposed to happen _before_ ignores.+ if(WordBreak2PositionOffset >= 0) WordUnbreaks |= KBTS_WORD_BREAK_BITS(0, 1);+ break;++ // (RI RI)* RI x RI+ KBTS_C2(RI, RI):+ WordBreakHistory = 0;+ // fallthrough+ KBTS_C2(HL, SQ):+ KBTS_C2(ALnep, ALnep): KBTS_C2(ALnep, ALep): KBTS_C2(ALnep, HL): KBTS_C2(ALnep, NM): KBTS_C2(ALnep, ENL):+ KBTS_C2(ALep, ALnep): KBTS_C2(ALep, ALep): KBTS_C2(ALep, HL): KBTS_C2(ALep, NM): KBTS_C2(ALep, ENL):+ KBTS_C2(HL, ALnep): KBTS_C2(HL, ALep): KBTS_C2(HL, HL): KBTS_C2(HL, NM): KBTS_C2(HL, ENL):+ KBTS_C2(NM, ALnep): KBTS_C2(NM, ALep): KBTS_C2(NM, HL): KBTS_C2(NM, NM): KBTS_C2(NM, ENL):+ KBTS_C2(KA, KA): KBTS_C2(KA, ENL):+ KBTS_C2(ENL, ALnep): KBTS_C2(ENL, ALep): KBTS_C2(ENL, HL): KBTS_C2(ENL, NM): KBTS_C2(ENL, KA): KBTS_C2(ENL, ENL):+ WordUnbreaks |= KBTS_WORD_BREAK_BITS(0, 1); break;+ }++ switch(WordBreakHistory & 0xFFFFFF)+ {+ KBTS_C3(ALnep, ML, ALnep): KBTS_C3(ALnep, ML, ALep): KBTS_C3(ALnep, ML, HL):+ KBTS_C3(ALnep, MNL, ALnep): KBTS_C3(ALnep, MNL, ALep): KBTS_C3(ALnep, MNL, HL):+ KBTS_C3(ALnep, SQ, ALnep): KBTS_C3(ALnep, SQ, ALep): KBTS_C3(ALnep, SQ, HL):+ KBTS_C3(ALep, ML, ALnep): KBTS_C3(ALep, ML, ALep): KBTS_C3(ALep, ML, HL):+ KBTS_C3(ALep, MNL, ALnep): KBTS_C3(ALep, MNL, ALep): KBTS_C3(ALep, MNL, HL):+ KBTS_C3(ALep, SQ, ALnep): KBTS_C3(ALep, SQ, ALep): KBTS_C3(ALep, SQ, HL):+ KBTS_C3(HL, ML, ALnep): KBTS_C3(HL, ML, ALep): KBTS_C3(HL, ML, HL):+ KBTS_C3(HL, MNL, ALnep): KBTS_C3(HL, MNL, ALep): KBTS_C3(HL, MNL, HL):+ KBTS_C3(HL, SQ, ALnep): KBTS_C3(HL, SQ, ALep): KBTS_C3(HL, SQ, HL):+ KBTS_C3(HL, DQ, HL):+ KBTS_C3(NM, MN, NM): KBTS_C3(NM, MNL, NM): KBTS_C3(NM, SQ, NM):+ WordUnbreaks |= KBTS_WORD_BREAK_BITS(0, 1) | KBTS_WORD_BREAK_BITS(0, 2); break;+ }++ kbts_u32 EffectiveWordBreaks = WordBreaks & ~WordUnbreaks;+ if(EffectiveWordBreaks & KBTS_WORD_BREAK_BITS(2, 2))+ {+ kbts__DoBreak(State, PositionOffset2 + WordBreak2PositionOffset, KBTS_BREAK_FLAG_WORD, 0, 0, 0);+ }+ if(EndOfText)+ {+ // Always break at the end of the text.+ KBTS_BREAK(KBTS_BREAK_FLAG_WORD, 1);+ // Do not break after the end of the text.+ }++ State->WordBreaks = (kbts_u16)WordBreaks;+ State->WordUnbreaks = (kbts_u16)WordUnbreaks;+ State->LastWordBreakClass = WordBreakClass;+ State->WordBreak2PositionOffset = 0;+ State->WordBreakHistory = WordBreakHistory;+ }+ State->LastWordBreakClassIncludingIgnored = WordBreakClass;+ #undef KBTS_WORD_BREAK_BITS+ #undef KBTS_C2+ #undef KBTS_C3++ kbts_s16 LineBreak3PositionOffset = State->LineBreak3PositionOffset;+ kbts_s16 LineBreak2PositionOffset = State->LineBreak2PositionOffset;+ int HardLineBreak = 0;+ { // Line breaking.+ kbts_u64 LineBreaks = State->LineBreaks << 16;+ kbts_u64 LineUnbreaks = State->LineUnbreaks << 16;+ kbts_u64 LineUnbreaksAsync = State->LineUnbreaksAsync << 16;++ #define KBTS_C1(A) case KBTS_LINE_BREAK_CLASS_##A+ #define KBTS_C2(A, B) case (KBTS_LINE_BREAK_CLASS_##A << 8) | (KBTS_LINE_BREAK_CLASS_##B)+ #define KBTS_C3(A, B, C) case (KBTS_LINE_BREAK_CLASS_##A << 16) | (KBTS_LINE_BREAK_CLASS_##B << 8) | KBTS_LINE_BREAK_CLASS_##C+ #define KBTS_C4(A, B, C, D) case (KBTS_LINE_BREAK_CLASS_##A << 24) | (KBTS_LINE_BREAK_CLASS_##B << 16) | (KBTS_LINE_BREAK_CLASS_##C << 8) | KBTS_LINE_BREAK_CLASS_##D+ #define KBTS_REQUIRED_LINE_BREAK(Priority, Position) do {LineBreaks |= (kbts_u64)KBTS__LINE_BREAK_REQUIRED##Priority << ((Position) * 16);} while(0)+ #define KBTS_LINE_BREAK(Priority, Position) do {LineBreaks |= (kbts_u64)KBTS__LINE_BREAK_ALLOWED##Priority << ((Position) * 16);} while(0)+ #define KBTS_LINE_UNBREAK(Priority, Position) do {LineUnbreaks |= (kbts_u64)KBTS__LINE_BREAK_REQUIRED##Priority << ((Position) * 16);} while(0)+ #define KBTS_LINE_UNBREAK_ASYNC(Priority, Position) do {LineUnbreaksAsync |= (kbts_u64)KBTS__LINE_BREAK_REQUIRED##Priority << ((Position) * 16);} while(0)++ if(EndOfText)+ {+ // Depending on the current line break state, we might need very different breaks.+ // For now, we copy the transitions from the first row of the transition table, but+ // we might want to special-case these.+ LineBreakClass = KBTS_LINE_BREAK_CLASS_Onea;+ }+ else if(LineBreakClass > KBTS_LINE_BREAK_CLASS_COUNT)+ {+ // These guys have special rules.+ if((LineBreakClass == KBTS_LINE_BREAK_CLASS_CM) || (LineBreakClass == KBTS_LINE_BREAK_CLASS_ZWJ))+ {+ if(LineBreakClass == KBTS_LINE_BREAK_CLASS_ZWJ)+ {+ KBTS_LINE_UNBREAK_ASYNC(3, 0);+ }++ switch(LastLineBreakClass)+ {+ case KBTS_LINE_BREAK_CLASS_SOT:+ case KBTS_LINE_BREAK_CLASS_BK:+ case KBTS_LINE_BREAK_CLASS_CR:+ case KBTS_LINE_BREAK_CLASS_LF:+ case KBTS_LINE_BREAK_CLASS_NL:+ case KBTS_LINE_BREAK_CLASS_SP:+ case KBTS_LINE_BREAK_CLASS_ZW:+ LineBreakClass = KBTS_LINE_BREAK_CLASS_ALnea;+ break;++ default:+ // The standard says to treat X [CM ZWJ]* as X.+ // This means that we need to hoist [CM ZWJ] completely out of the line breaking logic.+ // However, we give our results in index offsets relative to the current glyph, so we+ // do have to acknowledge that we are skipping glyphs.+ goto LineBreakAbsorbCharacter;+ }+ }+ else if(LineBreakClass == KBTS_LINE_BREAK_CLASS_CJ)+ {+ LineBreakClass = (kbts_u8)((State->JapaneseLineBreakStyle == KBTS_JAPANESE_LINE_BREAK_STYLE_STRICT) ? KBTS_LINE_BREAK_CLASS_NSea : KBTS_LINE_BREAK_CLASS_IDea);+ }+ }++ if(LastLineBreakClass == LineBreakClass)+ {+ // @Incomplete: Handle repeats that aren't SP*.+ if(LineBreakClass == KBTS_LINE_BREAK_CLASS_SP)+ {+ goto LineBreakAbsorbCharacter;+ }+ }++ LineBreakHistory = (LineBreakHistory << 8) | LineBreakClass;++ if(EndOfText && (State->ConfigFlags & KBTS_BREAK_CONFIG_FLAG_END_OF_TEXT_GENERATES_HARD_LINE_BREAK))+ {+ // Always break at the end of text.+ KBTS_REQUIRED_LINE_BREAK(5, 1);++ // x QUPf _eot_+ if((LineBreakHistory & 0xFF00) == (KBTS_LINE_BREAK_CLASS_QUPf << 8))+ {+ KBTS_LINE_UNBREAK(3, 2);+ }+ }++ KBTS_LINE_BREAK(0, 0);+ KBTS_LINE_BREAK(0, 1);++ switch(LineBreakClass)+ {+ KBTS_C1(BK):+ KBTS_C1(CR):+ KBTS_C1(LF):+ KBTS_C1(NL):+ {+ KBTS_LINE_UNBREAK(4, 1);++ // This is the only place that's not the end of text where we generate hard line breaks.+ // When we see a hard line break, we want to reset the direction/script state, so that+ // we generate new direction/script breaks for the new paragraph.+ FlushFlags |= (KBTS__BREAK_FLUSH_FLAG_SCRIPT |+ KBTS__BREAK_FLUSH_FLAG_DIRECTION_2 |+ KBTS__BREAK_FLUSH_FLAG_DIRECTION_1 |+ KBTS__BREAK_FLUSH_FLAG_DIRECTION_PARAGRAPH);+ ScriptCount = 0;+ HardLineBreak = 1;++ KBTS_REQUIRED_LINE_BREAK(5, 0);+ } break;++ KBTS_C1(ZW): KBTS_LINE_BREAK(4, 0); KBTS_LINE_UNBREAK(4, 1); break;+ KBTS_C1(BB): KBTS_LINE_UNBREAK(0, 0); break;++ KBTS_C1(GLea):+ KBTS_C1(GLnea):+ KBTS_C1(OPea):+ KBTS_C1(OPnea): KBTS_LINE_UNBREAK(3, 0); break;++ KBTS_C1(WJ): KBTS_LINE_UNBREAK(3, 0); KBTS_LINE_UNBREAK(3, 1); break;++ KBTS_C1(CLea):+ KBTS_C1(CLnea):+ KBTS_C1(CPea):+ KBTS_C1(CPnea):+ KBTS_C1(EXea):+ KBTS_C1(EXnea):+ KBTS_C1(SY): KBTS_LINE_UNBREAK(3, 1); break;++ KBTS_C1(IS): KBTS_LINE_UNBREAK(2, 1); break;++ KBTS_C1(SP): KBTS_LINE_UNBREAK(4, 1); KBTS_LINE_BREAK(2, 0); break;++ KBTS_C1(QU): KBTS_LINE_UNBREAK(1, 1); KBTS_LINE_UNBREAK(1, 0); break;+ KBTS_C1(QUPi): KBTS_LINE_UNBREAK(1, 0); break;+ KBTS_C1(QUPf): KBTS_LINE_UNBREAK(1, 1); break;+ KBTS_C1(CB): KBTS_LINE_BREAK(1, 0); KBTS_LINE_BREAK(1, 1); break;++ KBTS_C1(BAnea):+ KBTS_C1(BAea):+ KBTS_C1(HYPHEN):+ KBTS_C1(HY):+ KBTS_C1(NSnea):+ KBTS_C1(NSea):+ KBTS_C1(INnea):+ KBTS_C1(INea):+ KBTS_LINE_UNBREAK(0, 1); break;+ }++ switch(LineBreakHistory & 0xFFFF)+ {+ KBTS_C2(CR, LF): KBTS_LINE_UNBREAK(5, 1); break;+ KBTS_C2(ZW, SP): KBTS_LINE_BREAK(4, 0); break;+++ KBTS_C2(OPea, QUPi):+ KBTS_C2(GLea, QUPi):+ KBTS_C2(OPea, SP):+ KBTS_C2(OPnea,SP):+ KBTS_LINE_UNBREAK(3, 0);+ break;++ KBTS_C2(SOT, QUPi):+ KBTS_C2(BK, QUPi):+ KBTS_C2(CR, QUPi):+ KBTS_C2(LF, QUPi):+ KBTS_C2(NL, QUPi):+ KBTS_C2(SP, QUPi):+ KBTS_C2(ZW, QUPi):+ KBTS_C2(GLnea, QUPi):+ KBTS_C2(QU, QUPi):+ KBTS_C2(OPnea, QUPi):+ KBTS_LINE_UNBREAK(1, 1);+ KBTS_LINE_UNBREAK(1, 0);+ KBTS_LINE_UNBREAK(3, 0);+ break;++ KBTS_C2(QUPi, QUPi):+ KBTS_LINE_UNBREAK(3, 0);+ KBTS_LINE_UNBREAK(1, 2);+ KBTS_LINE_UNBREAK(1, 1);+ KBTS_LINE_UNBREAK(1, 0);+ break;++ KBTS_C2(QUPf, QUPi):+ KBTS_LINE_UNBREAK(1, 1);+ KBTS_LINE_UNBREAK(1, 0);+ KBTS_LINE_UNBREAK(3, 0);+ KBTS_LINE_UNBREAK(3, 2);+ KBTS_LINE_UNBREAK(1, 1);+ break;++ KBTS_C2(QUPf, GLnea):+ KBTS_LINE_UNBREAK(3, 2);+ KBTS_LINE_UNBREAK(3, 1);+ KBTS_LINE_UNBREAK(1, 1);+ break;++ KBTS_C2(QUPf, BK):+ KBTS_C2(QUPf, CR):+ KBTS_C2(QUPf, LF):+ KBTS_C2(QUPf, NL):+ KBTS_C2(QUPf, ZW):+ KBTS_C2(QUPf, WJ):+ KBTS_C2(QUPf, CLnea):+ KBTS_C2(QUPf, CPnea):+ KBTS_C2(QUPf, EXnea):+ KBTS_C2(QUPf, SY):+ KBTS_C2(QUPf, IS):+ KBTS_C2(QUPf, SP):+ KBTS_LINE_UNBREAK(3, 2);+ KBTS_LINE_UNBREAK(1, 1);+ break;++ KBTS_C2(QUPf, QUPf):+ KBTS_LINE_UNBREAK(3, 2);+ KBTS_LINE_UNBREAK(1, 1);+ KBTS_LINE_UNBREAK(1, 0);+ break;++ KBTS_C2(QUPf, QU):+ KBTS_LINE_UNBREAK(3, 2);+ KBTS_LINE_UNBREAK(1, 1);+ KBTS_LINE_UNBREAK(1, 0);+ break;++ KBTS_C2(QUPf, GLea):+ KBTS_LINE_UNBREAK(3, 2);+ KBTS_LINE_UNBREAK(3, 1);+ break;++ KBTS_C2(QUPf, CPea):+ KBTS_C2(QUPf, CLea):+ KBTS_C2(QUPf, EXea):+ KBTS_LINE_UNBREAK(3, 2);+ break;++ KBTS_C2(QUPi, QU):+ KBTS_LINE_UNBREAK(1, 1);+ KBTS_LINE_UNBREAK(1, 0);+ KBTS_LINE_UNBREAK(1, 2);+ break;++ KBTS_C2(QUPi, QUPf):+ KBTS_LINE_UNBREAK(1, 1);+ KBTS_LINE_UNBREAK(1, 0);+ KBTS_LINE_UNBREAK(1, 2);+ break;++ KBTS_C2(QUPi, GLnea):+ KBTS_LINE_UNBREAK(1, 2);+ KBTS_LINE_UNBREAK(3, 1);+ break;++ KBTS_C2(QUPi, Onea): KBTS_C2(QUPi, Ope): KBTS_C2(QUPi, BK): KBTS_C2(QUPi, CR): KBTS_C2(QUPi, LF): KBTS_C2(QUPi, NL): KBTS_C2(QUPi, SP): KBTS_C2(QUPi, ZW):+ KBTS_C2(QUPi, WJ): KBTS_C2(QUPi, CLnea): KBTS_C2(QUPi, CPnea): KBTS_C2(QUPi, EXnea): KBTS_C2(QUPi, SY): KBTS_C2(QUPi, BAnea):+ KBTS_C2(QUPi, OPnea): KBTS_C2(QUPi, IS): KBTS_C2(QUPi, NSnea): KBTS_C2(QUPi, B2): KBTS_C2(QUPi, CB):+ KBTS_C2(QUPi, HY): KBTS_C2(QUPi, HYPHEN): KBTS_C2(QUPi, INnea): KBTS_C2(QUPi, BB): KBTS_C2(QUPi, HL): KBTS_C2(QUPi, ALnea): KBTS_C2(QUPi, NU): KBTS_C2(QUPi, PRnea):+ KBTS_C2(QUPi, IDnea): KBTS_C2(QUPi, IDpe): KBTS_C2(QUPi, EBnea): KBTS_C2(QUPi, POnea): KBTS_C2(QUPi, JV): KBTS_C2(QUPi, JT): KBTS_C2(QUPi, AP): KBTS_C2(QUPi, AK):+ KBTS_C2(QUPi, DOTTED_CIRCLE): KBTS_C2(QUPi, AS): KBTS_C2(QUPi, VF): KBTS_C2(QUPi, VI): KBTS_C2(QUPi, RI):+ KBTS_LINE_UNBREAK(1, 2); break;+++ KBTS_C2(QUPf, Onea): KBTS_C2(QUPf, Ope):+ KBTS_C2(QUPf, BAnea):+ KBTS_C2(QUPf, OPnea): KBTS_C2(QUPf, NSnea): KBTS_C2(QUPf, B2): KBTS_C2(QUPf, CB):+ KBTS_C2(QUPf, HY): KBTS_C2(QUPf, HYPHEN): KBTS_C2(QUPf, INnea): KBTS_C2(QUPf, BB): KBTS_C2(QUPf, HL): KBTS_C2(QUPf, ALnea): KBTS_C2(QUPf, NU): KBTS_C2(QUPf, PRnea):+ KBTS_C2(QUPf, IDnea): KBTS_C2(QUPf, IDpe): KBTS_C2(QUPf, EBnea): KBTS_C2(QUPf, POnea): KBTS_C2(QUPf, JV): KBTS_C2(QUPf, JT): KBTS_C2(QUPf, AP): KBTS_C2(QUPf, AK):+ KBTS_C2(QUPf, DOTTED_CIRCLE): KBTS_C2(QUPf, AS): KBTS_C2(QUPf, VF): KBTS_C2(QUPf, VI): KBTS_C2(QUPf, RI):+ KBTS_LINE_UNBREAK(1, 1); break;++ KBTS_C2(SOT, QU): KBTS_C2(SOT, QUPf):+ KBTS_C2(Onea, QU): KBTS_C2(Ope, QU): KBTS_C2(BK, QU): KBTS_C2(CR, QU): KBTS_C2(LF, QU): KBTS_C2(NL, QU): KBTS_C2(SP, QU): KBTS_C2(ZW, QU):+ KBTS_C2(WJ, QU): KBTS_C2(GLnea, QU): KBTS_C2(CLnea, QU): KBTS_C2(CPnea, QU): KBTS_C2(EXnea, QU): KBTS_C2(SY, QU): KBTS_C2(BAnea, QU):+ KBTS_C2(OPnea, QU): KBTS_C2(QU, QU): KBTS_C2(IS, QU): KBTS_C2(NSnea, QU): KBTS_C2(B2, QU): KBTS_C2(CB, QU):+ KBTS_C2(HY, QU): KBTS_C2(HYPHEN, QU): KBTS_C2(INnea, QU): KBTS_C2(BB, QU): KBTS_C2(HL, QU): KBTS_C2(ALnea, QU): KBTS_C2(NU, QU): KBTS_C2(PRnea, QU):+ KBTS_C2(IDnea, QU): KBTS_C2(IDpe, QU): KBTS_C2(EBnea, QU): KBTS_C2(POnea, QU): KBTS_C2(JV, QU): KBTS_C2(JT, QU): KBTS_C2(AP, QU): KBTS_C2(AK, QU):+ KBTS_C2(DOTTED_CIRCLE, QU): KBTS_C2(AS, QU): KBTS_C2(VF, QU): KBTS_C2(VI, QU): KBTS_C2(RI, QU):+ KBTS_C2(Onea, QUPi): KBTS_C2(Ope, QUPi):+ KBTS_C2(WJ, QUPi): KBTS_C2(CLnea, QUPi): KBTS_C2(CPnea, QUPi): KBTS_C2(EXnea, QUPi): KBTS_C2(SY, QUPi): KBTS_C2(BAnea, QUPi):+ KBTS_C2(IS, QUPi):+ KBTS_C2(NSnea, QUPi):+ KBTS_C2(B2, QUPi):+ KBTS_C2(CB, QUPi):+ KBTS_C2(HY, QUPi): KBTS_C2(HYPHEN, QUPi): KBTS_C2(INnea, QUPi): KBTS_C2(BB, QUPi): KBTS_C2(HL, QUPi): KBTS_C2(ALnea, QUPi): KBTS_C2(NU, QUPi): KBTS_C2(PRnea, QUPi):+ KBTS_C2(IDnea, QUPi): KBTS_C2(IDpe, QUPi): KBTS_C2(EBnea, QUPi): KBTS_C2(POnea, QUPi): KBTS_C2(JV, QUPi): KBTS_C2(JT, QUPi): KBTS_C2(AP, QUPi): KBTS_C2(AK, QUPi):+ KBTS_C2(DOTTED_CIRCLE, QUPi): KBTS_C2(AS, QUPi): KBTS_C2(VF, QUPi): KBTS_C2(VI, QUPi): KBTS_C2(RI, QUPi):+ KBTS_C2(Onea, QUPf): KBTS_C2(Ope, QUPf): KBTS_C2(BK, QUPf): KBTS_C2(CR, QUPf): KBTS_C2(LF, QUPf): KBTS_C2(NL, QUPf): KBTS_C2(SP, QUPf): KBTS_C2(ZW, QUPf):+ KBTS_C2(WJ, QUPf): KBTS_C2(GLnea, QUPf): KBTS_C2(CLnea, QUPf): KBTS_C2(CPnea, QUPf): KBTS_C2(EXnea, QUPf): KBTS_C2(SY, QUPf): KBTS_C2(BAnea, QUPf):+ KBTS_C2(OPnea, QUPf): KBTS_C2(QU, QUPf): KBTS_C2(IS, QUPf): KBTS_C2(NSnea, QUPf): KBTS_C2(B2, QUPf): KBTS_C2(CB, QUPf):+ KBTS_C2(HY, QUPf): KBTS_C2(HYPHEN, QUPf): KBTS_C2(INnea, QUPf): KBTS_C2(BB, QUPf): KBTS_C2(HL, QUPf): KBTS_C2(ALnea, QUPf): KBTS_C2(NU, QUPf): KBTS_C2(PRnea, QUPf):+ KBTS_C2(IDnea, QUPf): KBTS_C2(IDpe, QUPf): KBTS_C2(EBnea, QUPf): KBTS_C2(POnea, QUPf): KBTS_C2(JV, QUPf): KBTS_C2(JT, QUPf): KBTS_C2(AP, QUPf): KBTS_C2(AK, QUPf):+ KBTS_C2(DOTTED_CIRCLE, QUPf): KBTS_C2(AS, QUPf): KBTS_C2(VF, QUPf): KBTS_C2(VI, QUPf): KBTS_C2(RI, QUPf):+ KBTS_LINE_UNBREAK(1, 1); KBTS_LINE_UNBREAK(1, 0); break;++ KBTS_C2(HL, NU): KBTS_C2(ALnea, NU): KBTS_C2(ALea, NU): KBTS_C2(DOTTED_CIRCLE, NU):+ KBTS_C2(NU, ALnea): KBTS_C2(NU, ALea): KBTS_C2(NU, DOTTED_CIRCLE): KBTS_C2(NU, HL):+ KBTS_C2(PRnea, IDnea): KBTS_C2(PRnea, IDea): KBTS_C2(PRnea, IDpe): KBTS_C2(PRnea, EBea): KBTS_C2(PRnea, EBnea): KBTS_C2(PRnea, EM):+ KBTS_C2(PRea, IDnea): KBTS_C2(PRea, IDea): KBTS_C2(PRea, IDpe): KBTS_C2(PRea, EBea): KBTS_C2(PRea, EBnea): KBTS_C2(PRea, EM):+ KBTS_C2(IDnea, POea): KBTS_C2(IDnea, POnea): KBTS_C2(IDea, POea): KBTS_C2(IDea, POnea): KBTS_C2(IDpe, POea): KBTS_C2(IDpe, POnea):+ KBTS_C2(EBnea, POea): KBTS_C2(EBnea, POnea): KBTS_C2(EBea, POea): KBTS_C2(EBea, POnea): KBTS_C2(EM, POea): KBTS_C2(EM, POnea):+ KBTS_C2(PRea, ALea): KBTS_C2(PRea, ALnea): KBTS_C2(PRea, DOTTED_CIRCLE): KBTS_C2(PRea, HL):+ KBTS_C2(PRnea, ALea): KBTS_C2(PRnea, ALnea): KBTS_C2(PRnea, DOTTED_CIRCLE): KBTS_C2(PRnea, HL):+ KBTS_C2(POea, ALea): KBTS_C2(POea, ALnea): KBTS_C2(POea, DOTTED_CIRCLE): KBTS_C2(POea, HL):+ KBTS_C2(POnea, ALea): KBTS_C2(POnea, ALnea): KBTS_C2(POnea, DOTTED_CIRCLE): KBTS_C2(POnea, HL):+ KBTS_C2(ALea, PRea): KBTS_C2(ALea, PRnea): KBTS_C2(ALea, POea): KBTS_C2(ALea, POnea):+ KBTS_C2(ALnea, PRea): KBTS_C2(ALnea, PRnea): KBTS_C2(ALnea, POea): KBTS_C2(ALnea, POnea):+ KBTS_C2(DOTTED_CIRCLE, PRea): KBTS_C2(DOTTED_CIRCLE, PRnea): KBTS_C2(DOTTED_CIRCLE, POea): KBTS_C2(DOTTED_CIRCLE, POnea):+ KBTS_C2(HL, PRea): KBTS_C2(HL, PRnea): KBTS_C2(HL, POea): KBTS_C2(HL, POnea):+ KBTS_C2(NU, POea): KBTS_C2(NU, POnea): KBTS_C2(NU, PRea): KBTS_C2(NU, PRnea): KBTS_C2(NU, NU):+ KBTS_C2(POea, NU): KBTS_C2(POnea, NU): KBTS_C2(PRea, NU): KBTS_C2(PRnea, NU):+ KBTS_C2(SY, HL):+ KBTS_C2(JL, JL): KBTS_C2(JL, JV): KBTS_C2(JL, H2): KBTS_C2(JL, H3):+ KBTS_C2(JV, JV): KBTS_C2(JV, JT): KBTS_C2(H2, JV): KBTS_C2(H2, JT):+ KBTS_C2(JT, JT): KBTS_C2(H3, JT):+ KBTS_C2(JL, POea): KBTS_C2(JL, POnea): KBTS_C2(JV, POea): KBTS_C2(JV, POnea): KBTS_C2(JT, POea): KBTS_C2(JT, POnea):+ KBTS_C2(H2, POea): KBTS_C2(H2, POnea): KBTS_C2(H3, POea): KBTS_C2(H3, POnea):+ KBTS_C2(PRea, JL): KBTS_C2(PRea, JV): KBTS_C2(PRea, JT): KBTS_C2(PRea, H2): KBTS_C2(PRea, H3):+ KBTS_C2(PRnea, JL): KBTS_C2(PRnea, JV): KBTS_C2(PRnea, JT): KBTS_C2(PRnea, H2): KBTS_C2(PRnea, H3):+ KBTS_C2(ALea, ALea): KBTS_C2(ALea, ALnea): KBTS_C2(ALea, DOTTED_CIRCLE): KBTS_C2(ALea, HL):+ KBTS_C2(ALnea, ALea): KBTS_C2(ALnea, ALnea): KBTS_C2(ALnea, DOTTED_CIRCLE): KBTS_C2(ALnea, HL):+ KBTS_C2(DOTTED_CIRCLE, ALea): KBTS_C2(DOTTED_CIRCLE, ALnea): KBTS_C2(DOTTED_CIRCLE, DOTTED_CIRCLE): KBTS_C2(DOTTED_CIRCLE, HL):+ KBTS_C2(HL, ALea): KBTS_C2(HL, ALnea): KBTS_C2(HL, DOTTED_CIRCLE): KBTS_C2(HL, HL):+ KBTS_C2(AP, AK): KBTS_C2(AP, DOTTED_CIRCLE): KBTS_C2(AP, AS):+ KBTS_C2(AK, VF): KBTS_C2(AK, VI): KBTS_C2(DOTTED_CIRCLE, VF): KBTS_C2(DOTTED_CIRCLE, VI): KBTS_C2(AS, VF): KBTS_C2(AS, VI):+ KBTS_C2(IS, ALea): KBTS_C2(IS, ALnea): KBTS_C2(IS, DOTTED_CIRCLE): KBTS_C2(IS, HL):+ KBTS_C2(ALea, OPnea): KBTS_C2(ALnea, OPnea): KBTS_C2(DOTTED_CIRCLE, OPnea): KBTS_C2(HL, OPnea): KBTS_C2(NU, OPnea):+ KBTS_C2(CPnea, ALea): KBTS_C2(CPnea, ALnea): KBTS_C2(CPnea, DOTTED_CIRCLE): KBTS_C2(CPnea, HL): KBTS_C2(CPnea, NU):+ KBTS_C2(EBea, EM): KBTS_C2(EBnea, EM): KBTS_C2(Ope, EM): KBTS_C2(IDpe, EM):+ KBTS_C2(HY, NU): KBTS_C2(IS, NU):+ KBTS_LINE_UNBREAK(0, 1); break;++ KBTS_C2(Oea, GLea):KBTS_C2(Oea, GLnea):+ KBTS_C2(Onea, GLea):KBTS_C2(Onea, GLnea):+ KBTS_C2(Ope, GLea):KBTS_C2(Ope, GLnea):+ KBTS_C2(BK, GLea):KBTS_C2(BK, GLnea):+ KBTS_C2(CR, GLea):KBTS_C2(CR, GLnea):+ KBTS_C2(LF, GLea):KBTS_C2(LF, GLnea):+ KBTS_C2(NL, GLea):KBTS_C2(NL, GLnea):+ KBTS_C2(ZW, GLea):KBTS_C2(ZW, GLnea):+ KBTS_C2(WJ, GLea):KBTS_C2(WJ, GLnea):+ KBTS_C2(GLea, GLea):KBTS_C2(GLea, GLnea):+ KBTS_C2(GLnea, GLea):KBTS_C2(GLnea, GLnea):+ KBTS_C2(CLea, GLea):KBTS_C2(CLea, GLnea):+ KBTS_C2(CLnea, GLea):KBTS_C2(CLnea, GLnea):+ KBTS_C2(CPea, GLea):KBTS_C2(CPea, GLnea):+ KBTS_C2(CPnea, GLea):KBTS_C2(CPnea, GLnea):+ KBTS_C2(EXea, GLea):KBTS_C2(EXea, GLnea):+ KBTS_C2(EXnea, GLea):KBTS_C2(EXnea, GLnea):+ KBTS_C2(SY, GLea):KBTS_C2(SY, GLnea):+ KBTS_C2(OPea, GLea):KBTS_C2(OPea, GLnea):+ KBTS_C2(OPnea, GLea):KBTS_C2(OPnea, GLnea):+ KBTS_C2(QU, GLea):KBTS_C2(QU, GLnea):+ KBTS_C2(QUPi, GLea):+ KBTS_C2(IS, GLea):KBTS_C2(IS, GLnea):+ KBTS_C2(NSea, GLea):KBTS_C2(NSea, GLnea):+ KBTS_C2(NSnea, GLea):KBTS_C2(NSnea, GLnea):+ KBTS_C2(B2, GLea):KBTS_C2(B2, GLnea):+ KBTS_C2(CB, GLea):KBTS_C2(CB, GLnea):+ KBTS_C2(INea, GLea):KBTS_C2(INea, GLnea):+ KBTS_C2(INnea, GLea):KBTS_C2(INnea, GLnea):+ KBTS_C2(BB, GLea):KBTS_C2(BB, GLnea):+ KBTS_C2(HL, GLea):KBTS_C2(HL, GLnea):+ KBTS_C2(ALea, GLea):KBTS_C2(ALea, GLnea):+ KBTS_C2(ALnea, GLea):KBTS_C2(ALnea, GLnea):+ KBTS_C2(NU, GLea):KBTS_C2(NU, GLnea):+ KBTS_C2(PRea, GLea):KBTS_C2(PRea, GLnea):+ KBTS_C2(PRnea, GLea):KBTS_C2(PRnea, GLnea):+ KBTS_C2(IDea, GLea):KBTS_C2(IDea, GLnea):+ KBTS_C2(IDnea, GLea):KBTS_C2(IDnea, GLnea):+ KBTS_C2(IDpe, GLea):KBTS_C2(IDpe, GLnea):+ KBTS_C2(EBea, GLea):KBTS_C2(EBea, GLnea):+ KBTS_C2(EBnea, GLea):KBTS_C2(EBnea, GLnea):+ KBTS_C2(EM, GLea):KBTS_C2(EM, GLnea):+ KBTS_C2(POea, GLea):KBTS_C2(POea, GLnea):+ KBTS_C2(POnea, GLea):KBTS_C2(POnea, GLnea):+ KBTS_C2(JL, GLea):KBTS_C2(JL, GLnea):+ KBTS_C2(JV, GLea):KBTS_C2(JV, GLnea):+ KBTS_C2(JT, GLea):KBTS_C2(JT, GLnea):+ KBTS_C2(H2, GLea):KBTS_C2(H2, GLnea):+ KBTS_C2(H3, GLea):KBTS_C2(H3, GLnea):+ KBTS_C2(AP, GLea):KBTS_C2(AP, GLnea):+ KBTS_C2(AK, GLea):KBTS_C2(AK, GLnea):+ KBTS_C2(DOTTED_CIRCLE, GLea):KBTS_C2(DOTTED_CIRCLE, GLnea):+ KBTS_C2(AS, GLea):KBTS_C2(AS, GLnea):+ KBTS_C2(VF, GLea):KBTS_C2(VF, GLnea):+ KBTS_C2(VI, GLea):KBTS_C2(VI, GLnea):+ KBTS_C2(RI, GLea):KBTS_C2(RI, GLnea):+ KBTS_LINE_UNBREAK(3, 1); break;+++ KBTS_C2(CLea, NSnea): KBTS_C2(CLea, NSea): KBTS_C2(CLnea, NSnea): KBTS_C2(CLnea, NSea):+ KBTS_C2(CPea, NSnea): KBTS_C2(CPea, NSea): KBTS_C2(CPnea, NSnea): KBTS_C2(CPnea, NSea):+ KBTS_C2(B2, B2):+ KBTS_LINE_UNBREAK(2, 1); break;++ KBTS_C2(RI, RI): // (RI RI)* RI x RI+ KBTS_LINE_UNBREAK(0, 1);+ LineBreakHistory = 0;+ break;+ }++ switch(LineBreakHistory & 0xFFFFFF)+ {+ KBTS_C3(SOT, QUPi, SP): KBTS_C3(BK, QUPi, SP): KBTS_C3(CR, QUPi, SP): KBTS_C3(LF, QUPi, SP): KBTS_C3(NL, QUPi, SP): KBTS_C3(OPea, QUPi, SP): KBTS_C3(OPnea, QUPi, SP):+ KBTS_C3(SP, QUPi, SP): KBTS_C3(ZW, QUPi, SP): KBTS_C3(QU, QUPi, SP): KBTS_C3(QUPi, QUPi, SP): KBTS_C3(QUPf, QUPi, SP): KBTS_C3(GLea, QUPi, SP): KBTS_C3(GLnea, QUPi, SP):+ KBTS_LINE_UNBREAK(3, 0); break;++ KBTS_C3(SP, IS, NU):+ KBTS_LINE_BREAK(3, 2); break;++ KBTS_C3(CLea, SP, NSnea): KBTS_C3(CLea, SP, NSea): KBTS_C3(CLnea, SP, NSnea): KBTS_C3(CLnea, SP, NSea):+ KBTS_C3(CPea, SP, NSnea): KBTS_C3(CPea, SP, NSea): KBTS_C3(CPnea, SP, NSnea): KBTS_C3(CPnea, SP, NSea):+ KBTS_C3(B2, SP, B2):+ KBTS_LINE_UNBREAK(2, 1); break;++ KBTS_C3(SOT, HY, ALnea): KBTS_C3(SOT, HY, ALea): KBTS_C3(SOT, HY, DOTTED_CIRCLE): KBTS_C3(SOT, HYPHEN, ALnea): KBTS_C3(SOT, HYPHEN, ALea): KBTS_C3(SOT, HYPHEN, DOTTED_CIRCLE):+ KBTS_C3(BK, HY, ALnea): KBTS_C3(BK, HY, ALea): KBTS_C3(BK, HY, DOTTED_CIRCLE): KBTS_C3(BK, HYPHEN, ALnea): KBTS_C3(BK, HYPHEN, ALea): KBTS_C3(BK, HYPHEN, DOTTED_CIRCLE):+ KBTS_C3(LF, HY, ALnea): KBTS_C3(LF, HY, ALea): KBTS_C3(LF, HY, DOTTED_CIRCLE): KBTS_C3(LF, HYPHEN, ALnea): KBTS_C3(LF, HYPHEN, ALea): KBTS_C3(LF, HYPHEN, DOTTED_CIRCLE):+ KBTS_C3(NL, HY, ALnea): KBTS_C3(NL, HY, ALea): KBTS_C3(NL, HY, DOTTED_CIRCLE): KBTS_C3(NL, HYPHEN, ALnea): KBTS_C3(NL, HYPHEN, ALea): KBTS_C3(NL, HYPHEN, DOTTED_CIRCLE):+ KBTS_C3(CR, HY, ALnea): KBTS_C3(CR, HY, ALea): KBTS_C3(CR, HY, DOTTED_CIRCLE): KBTS_C3(CR, HYPHEN, ALnea): KBTS_C3(CR, HYPHEN, ALea): KBTS_C3(CR, HYPHEN, DOTTED_CIRCLE):+ KBTS_C3(SP, HY, ALnea): KBTS_C3(SP, HY, ALea): KBTS_C3(SP, HY, DOTTED_CIRCLE): KBTS_C3(SP, HYPHEN, ALnea): KBTS_C3(SP, HYPHEN, ALea): KBTS_C3(SP, HYPHEN, DOTTED_CIRCLE):+ KBTS_C3(ZW, HY, ALnea): KBTS_C3(ZW, HY, ALea): KBTS_C3(ZW, HY, DOTTED_CIRCLE): KBTS_C3(ZW, HYPHEN, ALnea): KBTS_C3(ZW, HYPHEN, ALea): KBTS_C3(ZW, HYPHEN, DOTTED_CIRCLE):+ KBTS_C3(CB, HY, ALnea): KBTS_C3(CB, HY, ALea): KBTS_C3(CB, HY, DOTTED_CIRCLE): KBTS_C3(CB, HYPHEN, ALnea): KBTS_C3(CB, HYPHEN, ALea): KBTS_C3(CB, HYPHEN, DOTTED_CIRCLE):+ KBTS_C3(GLnea, HY, ALnea): KBTS_C3(GLnea, HY, ALea): KBTS_C3(GLnea, HY, DOTTED_CIRCLE): KBTS_C3(GLnea, HYPHEN, ALnea): KBTS_C3(GLnea, HYPHEN, ALea): KBTS_C3(GLnea, HYPHEN, DOTTED_CIRCLE):+ KBTS_C3(GLea, HY, ALnea): KBTS_C3(GLea, HY, ALea): KBTS_C3(GLea, HY, DOTTED_CIRCLE): KBTS_C3(GLea, HYPHEN, ALnea): KBTS_C3(GLea, HYPHEN, ALea): KBTS_C3(GLea, HYPHEN, DOTTED_CIRCLE):+ KBTS_C3(NU, SY, POea): KBTS_C3(NU, SY, POnea): KBTS_C3(NU, SY, PRea): KBTS_C3(NU, SY, PRnea): KBTS_C3(NU, SY, NU):+ KBTS_C3(NU, IS, POea): KBTS_C3(NU, IS, POnea): KBTS_C3(NU, IS, PRea): KBTS_C3(NU, IS, PRnea): KBTS_C3(NU, IS, NU):+ KBTS_C3(NU, CLea, POea): KBTS_C3(NU, CLea, POnea): KBTS_C3(NU, CLea, PRea): KBTS_C3(NU, CLea, PRnea):+ KBTS_C3(NU, CLnea, POea): KBTS_C3(NU, CLnea, POnea): KBTS_C3(NU, CLnea, PRea): KBTS_C3(NU, CLnea, PRnea):+ KBTS_C3(NU, CPea, POea): KBTS_C3(NU, CPea, POnea): KBTS_C3(NU, CPea, PRea): KBTS_C3(NU, CPea, PRnea):+ KBTS_C3(NU, CPnea, POea): KBTS_C3(NU, CPnea, POnea): KBTS_C3(NU, CPnea, PRea): KBTS_C3(NU, CPnea, PRnea):+ KBTS_C3(AK, VI, AK): KBTS_C3(AK, VI, DOTTED_CIRCLE): KBTS_C3(DOTTED_CIRCLE, VI, AK): KBTS_C3(DOTTED_CIRCLE, VI, DOTTED_CIRCLE): KBTS_C3(AS, VI, AK): KBTS_C3(AS, VI, DOTTED_CIRCLE):+ KBTS_LINE_UNBREAK(0, 1); break;++ KBTS_C3(POea, OPea, NU): KBTS_C3(POea, OPnea, NU): KBTS_C3(POnea, OPea, NU): KBTS_C3(POnea, OPnea, NU):+ KBTS_C3(PRea, OPea, NU): KBTS_C3(PRea, OPnea, NU): KBTS_C3(PRnea, OPea, NU): KBTS_C3(PRnea, OPnea, NU):+ KBTS_LINE_UNBREAK(0, 2); break;++ KBTS_C3(AK, AK, VF): KBTS_C3(AK, DOTTED_CIRCLE, VF): KBTS_C3(AK, AS, VF):+ KBTS_C3(DOTTED_CIRCLE, AK, VF): KBTS_C3(DOTTED_CIRCLE, DOTTED_CIRCLE, VF): KBTS_C3(DOTTED_CIRCLE, AS, VF):+ KBTS_C3(AS, AK, VF): KBTS_C3(AS, DOTTED_CIRCLE, VF): KBTS_C3(AS, AS, VF):+ KBTS_LINE_UNBREAK(0, 2); break;++ KBTS_C3(HL, BAnea, Oea): KBTS_C3(HL, BAnea, Onea): KBTS_C3(HL, BAnea, Ope): KBTS_C3(HL, BAnea, BK): KBTS_C3(HL, BAnea, CR): KBTS_C3(HL, BAnea, LF):+ KBTS_C3(HL, BAnea, NL): KBTS_C3(HL, BAnea, SP): KBTS_C3(HL, BAnea, ZW): KBTS_C3(HL, BAnea, WJ): KBTS_C3(HL, BAnea, GLea): KBTS_C3(HL, BAnea, GLnea):+ KBTS_C3(HL, BAnea, CLea): KBTS_C3(HL, BAnea, CLnea): KBTS_C3(HL, BAnea, CPea): KBTS_C3(HL, BAnea, CPnea): KBTS_C3(HL, BAnea, EXea): KBTS_C3(HL, BAnea, EXnea):+ KBTS_C3(HL, BAnea, SY): KBTS_C3(HL, BAnea, BAea): KBTS_C3(HL, BAnea, BAnea): KBTS_C3(HL, BAnea, OPea): KBTS_C3(HL, BAnea, OPnea): KBTS_C3(HL, BAnea, QU):+ KBTS_C3(HL, BAnea, QUPi): KBTS_C3(HL, BAnea, QUPf): KBTS_C3(HL, BAnea, IS): KBTS_C3(HL, BAnea, NSea): KBTS_C3(HL, BAnea, NSnea): KBTS_C3(HL, BAnea, B2):+ KBTS_C3(HL, BAnea, CB): KBTS_C3(HL, BAnea, HY): KBTS_C3(HL, BAnea, HYPHEN): KBTS_C3(HL, BAnea, INea): KBTS_C3(HL, BAnea, INnea): KBTS_C3(HL, BAnea, BB):+ KBTS_C3(HL, BAnea, ALea): KBTS_C3(HL, BAnea, ALnea): KBTS_C3(HL, BAnea, NU): KBTS_C3(HL, BAnea, PRea): KBTS_C3(HL, BAnea, PRnea): KBTS_C3(HL, BAnea, IDea):+ KBTS_C3(HL, BAnea, IDnea): KBTS_C3(HL, BAnea, IDpe): KBTS_C3(HL, BAnea, EBea): KBTS_C3(HL, BAnea, EBnea): KBTS_C3(HL, BAnea, EM): KBTS_C3(HL, BAnea, POea):+ KBTS_C3(HL, BAnea, POnea): KBTS_C3(HL, BAnea, JL): KBTS_C3(HL, BAnea, JV): KBTS_C3(HL, BAnea, JT): KBTS_C3(HL, BAnea, H2): KBTS_C3(HL, BAnea, H3):+ KBTS_C3(HL, BAnea, AP): KBTS_C3(HL, BAnea, AK): KBTS_C3(HL, BAnea, DOTTED_CIRCLE): KBTS_C3(HL, BAnea, AS): KBTS_C3(HL, BAnea, VF): KBTS_C3(HL, BAnea, VI): KBTS_C3(HL, BAnea, RI):+ KBTS_C3(HL, HYPHEN, Oea): KBTS_C3(HL, HYPHEN, Onea): KBTS_C3(HL, HYPHEN, Ope): KBTS_C3(HL, HYPHEN, BK): KBTS_C3(HL, HYPHEN, CR): KBTS_C3(HL, HYPHEN, LF):+ KBTS_C3(HL, HYPHEN, NL): KBTS_C3(HL, HYPHEN, SP): KBTS_C3(HL, HYPHEN, ZW): KBTS_C3(HL, HYPHEN, WJ): KBTS_C3(HL, HYPHEN, GLea): KBTS_C3(HL, HYPHEN, GLnea):+ KBTS_C3(HL, HYPHEN, CLea): KBTS_C3(HL, HYPHEN, CLnea): KBTS_C3(HL, HYPHEN, CPea): KBTS_C3(HL, HYPHEN, CPnea): KBTS_C3(HL, HYPHEN, EXea): KBTS_C3(HL, HYPHEN, EXnea):+ KBTS_C3(HL, HYPHEN, SY): KBTS_C3(HL, HYPHEN, BAea): KBTS_C3(HL, HYPHEN, BAnea): KBTS_C3(HL, HYPHEN, OPea): KBTS_C3(HL, HYPHEN, OPnea): KBTS_C3(HL, HYPHEN, QU):+ KBTS_C3(HL, HYPHEN, QUPi): KBTS_C3(HL, HYPHEN, QUPf): KBTS_C3(HL, HYPHEN, IS): KBTS_C3(HL, HYPHEN, NSea): KBTS_C3(HL, HYPHEN, NSnea): KBTS_C3(HL, HYPHEN, B2):+ KBTS_C3(HL, HYPHEN, CB): KBTS_C3(HL, HYPHEN, HY): KBTS_C3(HL, HYPHEN, HYPHEN): KBTS_C3(HL, HYPHEN, INea): KBTS_C3(HL, HYPHEN, INnea): KBTS_C3(HL, HYPHEN, BB):+ KBTS_C3(HL, HYPHEN, ALea): KBTS_C3(HL, HYPHEN, ALnea): KBTS_C3(HL, HYPHEN, NU): KBTS_C3(HL, HYPHEN, PRea): KBTS_C3(HL, HYPHEN, PRnea): KBTS_C3(HL, HYPHEN, IDea):+ KBTS_C3(HL, HYPHEN, IDnea): KBTS_C3(HL, HYPHEN, IDpe): KBTS_C3(HL, HYPHEN, EBea): KBTS_C3(HL, HYPHEN, EBnea): KBTS_C3(HL, HYPHEN, EM): KBTS_C3(HL, HYPHEN, POea):+ KBTS_C3(HL, HYPHEN, POnea): KBTS_C3(HL, HYPHEN, JL): KBTS_C3(HL, HYPHEN, JV): KBTS_C3(HL, HYPHEN, JT): KBTS_C3(HL, HYPHEN, H2): KBTS_C3(HL, HYPHEN, H3):+ KBTS_C3(HL, HYPHEN, AP): KBTS_C3(HL, HYPHEN, AK): KBTS_C3(HL, HYPHEN, DOTTED_CIRCLE): KBTS_C3(HL, HYPHEN, AS): KBTS_C3(HL, HYPHEN, VF): KBTS_C3(HL, HYPHEN, VI): KBTS_C3(HL, HYPHEN, RI):+ KBTS_C3(HL, HY, Oea): KBTS_C3(HL, HY, Onea): KBTS_C3(HL, HY, Ope): KBTS_C3(HL, HY, BK): KBTS_C3(HL, HY, CR): KBTS_C3(HL, HY, LF):+ KBTS_C3(HL, HY, NL): KBTS_C3(HL, HY, SP): KBTS_C3(HL, HY, ZW): KBTS_C3(HL, HY, WJ): KBTS_C3(HL, HY, GLea): KBTS_C3(HL, HY, GLnea):+ KBTS_C3(HL, HY, CLea): KBTS_C3(HL, HY, CLnea): KBTS_C3(HL, HY, CPea): KBTS_C3(HL, HY, CPnea): KBTS_C3(HL, HY, EXea): KBTS_C3(HL, HY, EXnea):+ KBTS_C3(HL, HY, SY): KBTS_C3(HL, HY, BAea): KBTS_C3(HL, HY, BAnea): KBTS_C3(HL, HY, OPea): KBTS_C3(HL, HY, OPnea): KBTS_C3(HL, HY, QU):+ KBTS_C3(HL, HY, QUPi): KBTS_C3(HL, HY, QUPf): KBTS_C3(HL, HY, IS): KBTS_C3(HL, HY, NSea): KBTS_C3(HL, HY, NSnea): KBTS_C3(HL, HY, B2):+ KBTS_C3(HL, HY, CB): KBTS_C3(HL, HY, HY): KBTS_C3(HL, HY, HYPHEN): KBTS_C3(HL, HY, INea): KBTS_C3(HL, HY, INnea): KBTS_C3(HL, HY, BB):+ KBTS_C3(HL, HY, ALea): KBTS_C3(HL, HY, ALnea): KBTS_C3(HL, HY, NU): KBTS_C3(HL, HY, PRea): KBTS_C3(HL, HY, PRnea): KBTS_C3(HL, HY, IDea):+ KBTS_C3(HL, HY, IDnea): KBTS_C3(HL, HY, IDpe): KBTS_C3(HL, HY, EBea): KBTS_C3(HL, HY, EBnea): KBTS_C3(HL, HY, EM): KBTS_C3(HL, HY, POea):+ KBTS_C3(HL, HY, POnea): KBTS_C3(HL, HY, JL): KBTS_C3(HL, HY, JV): KBTS_C3(HL, HY, JT): KBTS_C3(HL, HY, H2): KBTS_C3(HL, HY, H3):+ KBTS_C3(HL, HY, AP): KBTS_C3(HL, HY, AK): KBTS_C3(HL, HY, DOTTED_CIRCLE): KBTS_C3(HL, HY, AS): KBTS_C3(HL, HY, VF): KBTS_C3(HL, HY, VI): KBTS_C3(HL, HY, RI):+ KBTS_LINE_UNBREAK(0, 1); break;+ }++ switch(LineBreakHistory)+ {+ KBTS_C4(NU, SY, CLnea, POnea): KBTS_C4(NU, SY, CLnea, POea): KBTS_C4(NU, SY, CLnea, PRnea): KBTS_C4(NU, SY, CLnea, PRea):+ KBTS_C4(NU, SY, CLea, POnea): KBTS_C4(NU, SY, CLea, POea): KBTS_C4(NU, SY, CLea, PRnea): KBTS_C4(NU, SY, CLea, PRea):+ KBTS_C4(NU, SY, CPnea, POnea): KBTS_C4(NU, SY, CPnea, POea): KBTS_C4(NU, SY, CPnea, PRnea): KBTS_C4(NU, SY, CPnea, PRea):+ KBTS_C4(NU, SY, CPea, POnea): KBTS_C4(NU, SY, CPea, POea): KBTS_C4(NU, SY, CPea, PRnea): KBTS_C4(NU, SY, CPea, PRea):+ KBTS_C4(NU, IS, CLnea, POnea): KBTS_C4(NU, IS, CLnea, POea): KBTS_C4(NU, IS, CLnea, PRnea): KBTS_C4(NU, IS, CLnea, PRea):+ KBTS_C4(NU, IS, CLea, POnea): KBTS_C4(NU, IS, CLea, POea): KBTS_C4(NU, IS, CLea, PRnea): KBTS_C4(NU, IS, CLea, PRea):+ KBTS_C4(NU, IS, CPnea, POnea): KBTS_C4(NU, IS, CPnea, POea): KBTS_C4(NU, IS, CPnea, PRnea): KBTS_C4(NU, IS, CPnea, PRea):+ KBTS_C4(NU, IS, CPea, POnea): KBTS_C4(NU, IS, CPea, POea): KBTS_C4(NU, IS, CPea, PRnea): KBTS_C4(NU, IS, CPea, PRea):+ KBTS_LINE_UNBREAK(0, 1); break;++ KBTS_C4(POea, OPea, IS, NU): KBTS_C4(POea, OPnea, IS, NU): KBTS_C4(POnea, OPea, IS, NU): KBTS_C4(POnea, OPnea, IS, NU):+ KBTS_C4(PRea, OPea, IS, NU): KBTS_C4(PRea, OPnea, IS, NU): KBTS_C4(PRnea, OPea, IS, NU): KBTS_C4(PRnea, OPnea, IS, NU):+ KBTS_LINE_UNBREAK(0, 3); break;+ }++ if(StartOfText)+ {+ // Never break lines.+ KBTS_LINE_UNBREAK(5, 1);+ // Always break graphemes.+ KBTS_BREAK(KBTS_BREAK_FLAG_GRAPHEME, 1);+ }++ #undef KBTS_C1+ #undef KBTS_C2+ #undef KBTS_C3+ #undef KBTS_C4+ #undef KBTS_REQUIRED_LINE_BREAK+ #undef KBTS_LINE_BREAK+ #undef KBTS_LINE_UNBREAK++ {+ kbts_u64 EffectiveLineBreaks = LineBreaks & ~(LineUnbreaks | LineUnbreaksAsync);++ kbts__DoLineBreak(State, PositionOffset3 + LineBreak3PositionOffset, EffectiveLineBreaks >> 48);+ if(EndOfText)+ {+ kbts__DoLineBreak(State, PositionOffset2 + LineBreak2PositionOffset, EffectiveLineBreaks >> 32);+ { // @Cleanup: This is the same flag code as DoLineBreak, but we want to use FlagState buffering for this.+ // The only places where we want to manually call DoBreak is for asynchronous/buffered guys.+ kbts_u8 FlushedLineFlags = 0;+ if((EffectiveLineBreaks >> 16) & KBTS__LINE_BREAK_ALLOWED_MASK) FlushedLineFlags |= KBTS_BREAK_FLAG_LINE_SOFT;+ if((EffectiveLineBreaks >> 16) & KBTS__LINE_BREAK_REQUIRED_MASK) FlushedLineFlags |= KBTS_BREAK_FLAG_LINE_HARD;++ KBTS_BREAK(FlushedLineFlags, 1);+ }+ // Lines are never broken after the end of text.+ }+ }++ State->LineBreaks = LineBreaks;+ State->LineUnbreaks = LineUnbreaks;+ State->LineBreak2PositionOffset = 0;+ State->LineBreak3PositionOffset = LineBreak2PositionOffset;+ State->LastLineBreakClass = LineBreakClass;+ State->LineBreakHistory = LineBreakHistory;++ if(0)+ {+ LineBreakAbsorbCharacter:;+ State->LineBreak2PositionOffset -= (kbts_s16)PositionIncrement;+ State->LineBreak3PositionOffset -= (kbts_s16)PositionIncrement;+ }++ // This always gets updated.+ State->LineUnbreaksAsync = LineUnbreaksAsync;+ }++ // We flush scripts late because hard line breaks also want to flush scripts.+ //+ // If we have no active script at all, then either we are at the very beginning of the text,+ // or we have only seen common/inherited scripts so far.+ // Either way, we want everything before us to coerce to our type, so don't actually break,+ // and do not update the script break position.+ if((FlushFlags & KBTS__BREAK_FLUSH_FLAG_SCRIPT) &&+ ScriptCountAtBeginningOfUpdate)+ {+ kbts__DoBreak(State, ScriptPositionOffset, KBTS_BREAK_FLAG_SCRIPT, 0, 0, BreakScript);+ ScriptPositionOffset = 0;++ if(HardLineBreak)+ {+ // Put the next script break after the newline.+ ScriptPositionOffset = (kbts_s16)PositionIncrement;+ }+ }++ if(FlushFlags & KBTS__BREAK_FLUSH_FLAG_DIRECTION_2)+ {+ kbts__FlushDirection(State, &LastDirection, Bidirectional2, Bidirectional2PositionOffset);+ }+ if(FlushFlags & KBTS__BREAK_FLUSH_FLAG_DIRECTION_1)+ {+ kbts__FlushDirection(State, &LastDirection, Bidirectional1, Bidirectional1PositionOffset);+ }++ if(FlushFlags & KBTS__BREAK_FLUSH_FLAG_DIRECTION_PARAGRAPH)+ {+ // Reset direction state for the new paragraph.+ Bidirectional1 = 0;++ // Clear direction history.+ // This is necessary to uphold the invariant that the first direction break is always+ // on the first character of a paragraph.+ LastDirection = 0;++ // CAUTION: This needs to be updated _after_ calling kbts__FlushDirection!+ // Alternatively, we could load ParagraphStartPosition into a variable at the start of this function.+ State->ParagraphStartPosition = State->CurrentPosition + 1;++ kbts__BreakStateStartParagraph(State);++ if(State->UserParagraphDirection == KBTS_DIRECTION_DONT_KNOW)+ {+ kbts__DoBreak(State, 1, KBTS_BREAK_FLAG_PARAGRAPH_DIRECTION, 0, KBTS_DIRECTION_DONT_KNOW, 0);+ }+ }++ ScriptPositionOffset -= (kbts_s16)PositionIncrement;++ // This is where we flush the normal breaks that don't need any special position adjustment.+ kbts__DoBreak(State, PositionOffset3, (FlagState >> 24) & 0xFF, 0, 0, 0);+ if(EndOfText)+ {+ kbts__DoBreak(State, PositionOffset2, (FlagState >> 16) & 0xFF, 0, 0, 0);+ kbts__DoBreak(State, 0, (FlagState >> 8) & 0xFF, 0, 0, 0);+ kbts__DoBreak(State, (int)PositionIncrement, FlagState & 0xFF, 0, 0, 0);+ }++ State->FlagState = FlagState;+ Flags |= KBTS_BREAK_STATE_FLAG_STARTED;+ if(EndOfText) Flags |= KBTS_BREAK_STATE_FLAG_END;+ State->Flags = Flags;+ State->PositionOffset2 = (kbts_s16)-(int)PositionIncrement;+ State->PositionOffset3 = (kbts_s16)(PositionOffset2 - (int)PositionIncrement);+ State->CurrentPosition += PositionIncrement;++ if(FlushFlags & KBTS__BREAK_FLUSH_FLAG_DIRECTION_2)+ {+ // Only update the buffer if we've actually flushed something.+ State->BidirectionalClass2 = Bidirectional1;+ State->BidirectionalClass1 = BidirectionalClass;+ State->Bidirectional2PositionOffset = State->Bidirectional1PositionOffset - (kbts_s16)PositionIncrement;+ State->Bidirectional1PositionOffset = (kbts_s16)-(int)PositionIncrement;+ }+ State->LastDirection = (kbts_u8)LastDirection;++ State->ScriptPositionOffset = ScriptPositionOffset;+ State->ScriptCount = ScriptCount;+#undef KBTS_BREAK+#undef KBTS_BREAK2+}++KBTS_EXPORT void kbts_BreakEnd(kbts_break_state *State)+{+ // We pass 3, aka. ASCII end-of-text, at the end of text.+ kbts__BreakAddCodepoint(State, 3, 0, 1);+}++KBTS_EXPORT void kbts_BreakAddCodepoint(kbts_break_state *State, int Codepoint, int PositionIncrement, int EndOfText)+{+ kbts__BreakAddCodepoint(State, Codepoint, (kbts_u32)PositionIncrement, 0);++ if(EndOfText)+ {+ kbts_BreakEnd(State);+ }+}++KBTS_EXPORT int kbts_Break(kbts_break_state *State, kbts_break *Break)+{+ int Result = 0;++ if(State->BreakCount)+ {+ kbts_break *ToFlush = &State->Breaks[--State->BreakCount];++ *Break = *ToFlush;+ Result = 1;+ }++ return Result;+}++KBTS_EXPORT void kbts_GuessTextProperties(void *Text, int TextSizeInBytes, kbts_text_format Format, kbts_direction *Direction_, kbts_script *Script_)+{+ kbts_script Script = KBTS_SCRIPT_DONT_KNOW;+ kbts_direction Direction = KBTS_DIRECTION_DONT_KNOW;++ if(Text && (TextSizeInBytes > 0) && Format)+ {+ const char *At = (const char *)Text;+ const char *End = (const char *)Text + TextSizeInBytes;++ kbts_break_state BreakState;+ kbts_BreakBegin(&BreakState, KBTS_DIRECTION_DONT_KNOW, KBTS_JAPANESE_LINE_BREAK_STYLE_NORMAL, 0);++ while(((Script == KBTS_SCRIPT_DONT_KNOW) ||+ (Direction == KBTS_DIRECTION_DONT_KNOW)) &&+ (At < End))+ {+ kbts_u32 Codepoint = 0;+ kbts_u32 PositionIncrement = 1;++ switch(Format)+ {+ case KBTS_TEXT_FORMAT_UTF32:+ {+ Codepoint = *(kbts_u32 *)At;+ PositionIncrement = 4;++ } break;++ case KBTS_TEXT_FORMAT_UTF8:+ {+ kbts_decode Decode = kbts_DecodeUtf8(At, End - At);++ PositionIncrement = Decode.SourceCharactersConsumed;++ if(Decode.Valid)+ {+ Codepoint = Decode.Codepoint;+ }+ } break;+ }++ kbts_BreakAddCodepoint(&BreakState, Codepoint, PositionIncrement, (At + PositionIncrement) == End);+ kbts_break Break;+ while(kbts_Break(&BreakState, &Break))+ {+ if((Script == KBTS_SCRIPT_DONT_KNOW) && (Break.Flags & KBTS_BREAK_FLAG_SCRIPT))+ {+ Script = Break.Script;+ }++ if((Direction == KBTS_DIRECTION_DONT_KNOW) && (Break.Flags & KBTS_BREAK_FLAG_DIRECTION))+ {+ Direction = Break.Direction;+ }+ }++ At += PositionIncrement;+ }+ }++ if(Script_)+ {+ *Script_ = Script;+ }++ if(Direction_)+ {+ *Direction_ = Direction;+ }+}++KBTS_EXPORT void kbts_GuessTextPropertiesUtf32(const int *Utf32, int Utf32Count, kbts_direction *Direction, kbts_script *Script)+{+ kbts_GuessTextProperties((void *)Utf32, sizeof(int) * Utf32Count, KBTS_TEXT_FORMAT_UTF32, Direction, Script);+}++KBTS_EXPORT void kbts_GuessTextPropertiesUtf8(const char *Utf8, int Utf8Length, kbts_direction *Direction, kbts_script *Script)+{+ kbts_GuessTextProperties((void *)Utf8, Utf8Length, KBTS_TEXT_FORMAT_UTF8, Direction, Script);+}++KBTS_EXPORT void kbts_BreakBegin(kbts_break_state *State, kbts_direction ParagraphDirection, kbts_japanese_line_break_style JapaneseLineBreakStyle, kbts_break_config_flags ConfigFlags)+{+ if(State)+ {+ // @Speed: Clearing all the brackets isn't great.+ KBTS_MEMSET(State, 0, sizeof(*State));+ State->UserParagraphDirection = (kbts_u8)ParagraphDirection;+ State->ParagraphDirection = (kbts_u8)ParagraphDirection;+ State->JapaneseLineBreakStyle = JapaneseLineBreakStyle;+ State->ConfigFlags = ConfigFlags;++ // Force a direction break at the start of the text.+ State->LastDirection = KBTS_DIRECTION_COUNT;++ // These should be out-of-bounds while the buffers haven't filled up.+ State->PositionOffset2 = -100;+ State->PositionOffset3 = -100;+ State->WordBreak2PositionOffset = -100;+ State->LineBreak2PositionOffset = -100;+ State->LineBreak3PositionOffset = -100;+ State->Bidirectional1PositionOffset = -100;+ State->Bidirectional2PositionOffset = -100;++ kbts__BreakStateStartParagraph(State);++ if(ParagraphDirection)+ {+ kbts__DoBreak(State, 0, KBTS_BREAK_FLAG_PARAGRAPH_DIRECTION, 0, ParagraphDirection, 0);+ }+ }+}++KBTS_EXPORT void kbts_BreakEntireString(kbts_direction Direction, kbts_japanese_line_break_style JapaneseLineBreakStyle, kbts_break_config_flags ConfigFlags,+ const void *Input, int InputSizeInBytes, kbts_text_format InputFormat,+ kbts_break *Breaks, int IBreakCapacity, int *BreakCount,+ kbts_break_flags *BreakFlags, int IBreakFlagCapacity, int *BreakFlagCount)+{+ kbts_break_state BreakState = KBTS__ZERO;+ kbts_BreakBegin(&BreakState, Direction, JapaneseLineBreakStyle, ConfigFlags);++ char *InputElement = (char *)Input;+ char *End = (char *)Input + InputSizeInBytes;+ kbts_un BreaksWritten = 0;+ kbts_un MaxBreakPosition = 0;+ kbts_un BreakCapacity = (kbts_un)IBreakCapacity;+ kbts_un BreakFlagCapacity = (kbts_un)IBreakFlagCapacity;++ if(BreakFlags && BreakFlagCapacity)+ {+ KBTS_MEMSET(BreakFlags, 0, sizeof(kbts_break_flags) * BreakFlagCapacity);+ }++ while(InputElement < End)+ {+ kbts_u32 Codepoint = 0;+ kbts_un InputElementSize = 1;+ kbts_un SourceCharacterCount = 1;++ switch(InputFormat)+ {+ case KBTS_TEXT_FORMAT_UTF32:+ {+ Codepoint = *(kbts_u32 *)InputElement;++ InputElementSize = sizeof(kbts_u32);+ } break;++ case KBTS_TEXT_FORMAT_UTF8:+ {+ kbts_decode Decode = kbts_DecodeUtf8(InputElement, End - InputElement);++ if(Decode.Valid)+ {+ Codepoint = Decode.Codepoint;++ InputElementSize = Decode.SourceCharactersConsumed;+ SourceCharacterCount = Decode.SourceCharactersConsumed;+ }+ } break;+ }++ InputElement += InputElementSize;++ kbts_BreakAddCodepoint(&BreakState, Codepoint, (kbts_u32)SourceCharacterCount, InputElement >= End);+ kbts_break Break;+ while(kbts_Break(&BreakState, &Break))+ {+ if(Breaks && (BreaksWritten < BreakCapacity))+ {+ int Found = 0;+ kbts_un ExistingBreakCount = KBTS__MIN(BreaksWritten, BreakCapacity);++ // @Speed: Binary search!+ for(kbts_un ExistingBreakIndex = ExistingBreakCount;+ ExistingBreakIndex;+ --ExistingBreakIndex)+ {+ kbts_break *Existing = &Breaks[ExistingBreakIndex - 1];++ if(Existing->Position == Break.Position)+ {+ Existing->Flags |= Break.Flags;++ if(Break.Flags & KBTS_BREAK_FLAG_SCRIPT)+ {+ Existing->Script = Break.Script;+ }++ if(Break.Flags & KBTS_BREAK_FLAG_DIRECTION)+ {+ Existing->Direction = Break.Direction;+ }++ Found = 1;++ break;+ }+ }++ if(!Found)+ {+ Breaks[BreaksWritten] = Break;+ }+ }++ if(BreakFlags && ((kbts_u32)Break.Position < BreakFlagCapacity))+ {+ BreakFlags[Break.Position] |= Break.Flags;+ }++ MaxBreakPosition = KBTS__MAX(MaxBreakPosition, (kbts_u32)Break.Position);++ BreaksWritten += 1;+ }+ }++ if(!Breaks && BreakCount)+ {+ *BreakCount = (int)BreaksWritten;+ }+ if(!BreakFlags && BreakFlagCount)+ {+ *BreakFlagCount = (int)(MaxBreakPosition + 1);+ }+}++KBTS_EXPORT void kbts_BreakEntireStringUtf32(kbts_direction Direction, kbts_japanese_line_break_style JapaneseLineBreakStyle, kbts_break_config_flags ConfigFlags,+ const int *Utf32, int Utf32Count,+ kbts_break *Breaks, int BreakCapacity, int *BreakCount,+ kbts_break_flags *BreakFlags, int BreakFlagCapacity, int *BreakFlagCount)+{+ kbts_BreakEntireString(Direction, JapaneseLineBreakStyle, ConfigFlags, Utf32, sizeof(int) * Utf32Count, KBTS_TEXT_FORMAT_UTF32, Breaks, BreakCapacity, BreakCount, BreakFlags, BreakFlagCapacity, BreakFlagCount);+}+KBTS_EXPORT void kbts_BreakEntireStringUtf8(kbts_direction Direction, kbts_japanese_line_break_style JapaneseLineBreakStyle, kbts_break_config_flags ConfigFlags,+ const char *Utf8, int Utf8Length,+ kbts_break *Breaks, int BreakCapacity, int *BreakCount,+ kbts_break_flags *BreakFlags, int BreakFlagCapacity, int *BreakFlagCount)+{+ kbts_BreakEntireString(Direction, JapaneseLineBreakStyle, ConfigFlags, Utf8, Utf8Length, KBTS_TEXT_FORMAT_UTF8, Breaks, BreakCapacity, BreakCount, BreakFlags, BreakFlagCapacity, BreakFlagCount);+}++KBTS_EXPORT kbts_decode kbts_DecodeUtf8(const char *Utf8, kbts_un Length)+{+ kbts_decode Result = KBTS__ZERO;+ const char *Utf8Start = Utf8;++ if(Length)+ {+ kbts_u8 First = (kbts_u8)*Utf8++;+ kbts_un FollowupCharacterCount = 0;++ switch((First & 0xF0) >> 4)+ {+ case 0:+ case 1:+ case 2:+ case 3:+ case 4:+ case 5:+ case 6:+ case 7:+ {+ Result.Codepoint = First & 0x7F;+ Result.Valid = 1;+ }+ break;++ case 0xC:+ case 0xD:+ {+ FollowupCharacterCount = 1;+ Result.Codepoint = First & 0x1F;+ Result.Valid = 1;+ }+ break;++ case 0xE:+ {+ FollowupCharacterCount = 2;+ Result.Codepoint = First & 0xF;+ Result.Valid = 1;+ }+ break;++ case 0xF:+ {+ FollowupCharacterCount = 3;+ Result.Codepoint = First & 7;+ Result.Valid = 1;+ }+ break;+ }++ if(Length > FollowupCharacterCount)+ {+ KBTS__FOR(FollowupCharacterIndex, 0, FollowupCharacterCount)+ {+ kbts_u8 C = (kbts_u8)*Utf8++;++ if((C & 0xC0) == 0x80)+ {+ Result.Codepoint = (Result.Codepoint << 6) | (C & 0x3F);+ }+ else+ {+ Result.Valid = 0;++ break;+ }+ }+ }+ else+ {+ Result.Valid = 0;+ }+ }++ Result.SourceCharactersConsumed = (kbts_u32)(Utf8 - Utf8Start);++ return Result;+}++KBTS_EXPORT kbts_encode_utf8 kbts_EncodeUtf8(int Codepoint)+{+ kbts_encode_utf8 Result = KBTS__ZERO;++ if(Codepoint <= 0x7F)+ {+ Result.Encoded[0] = (char)Codepoint;+ Result.EncodedLength = 1;+ }+ else if(Codepoint <= 0x7FF)+ {+ Result.Encoded[1] = (Codepoint & 0x3F) | 0x80;+ Result.Encoded[0] = ((Codepoint >> 6) & 0x1F) | 0xC0;+ Result.EncodedLength = 2;+ }+ else if(Codepoint <= 0xFFFF)+ {+ Result.Encoded[2] = (Codepoint & 0x3F) | 0x80;+ Result.Encoded[1] = ((Codepoint >> 6) & 0x3F) | 0x80;+ Result.Encoded[0] = ((Codepoint >> 12) & 0xF) | 0xE0;+ Result.EncodedLength = 3;+ }+ else if(Codepoint <= 0x10FFFF)+ {+ Result.Encoded[3] = (Codepoint & 0x3F) | 0x80;+ Result.Encoded[2] = ((Codepoint >> 6) & 0x3F) | 0x80;+ Result.Encoded[1] = ((Codepoint >> 12) & 0x3F) | 0x80;+ Result.Encoded[0] = ((Codepoint >> 18) & 0x7) | 0xF0;+ Result.EncodedLength = 4;+ }++ Result.Valid = Result.EncodedLength > 0;+ return Result;+}++static int kbts__ShaperIsComplex(kbts_shaper Shaper)+{+ int Result = Shaper != KBTS_SHAPER_DEFAULT; // @Incomplete?++ return Result;+}++KBTS_EXPORT int kbts_ScriptIsComplex(kbts_script Script)+{+ if(Script >= KBTS_SCRIPT_COUNT)+ {+ Script = KBTS_SCRIPT_DONT_KNOW;+ }++ kbts__script_properties *Properties = &kbts__ScriptProperties[Script];+ int Result = kbts__ShaperIsComplex(Properties->Shaper);+ return Result;+}++#undef KBTS_X_FEATURES
+ kb-text-shape.cabal view
@@ -0,0 +1,157 @@+cabal-version: 2.2++-- This file has been generated from package.yaml by hpack version 0.38.1.+--+-- see: https://github.com/sol/hpack++name: kb-text-shape+version: 0.1.0.0+synopsis: Unicode segmentation and shaping using kb_text_shape+category: Font+homepage: https://github.com/dpwiz/kb-text-shape#readme+bug-reports: https://github.com/dpwiz/kb-text-shape/issues+author: IC Rainbow+maintainer: aenor.realm@gmail.com+copyright: 2025 IC Rainbow+license: BSD-3-Clause+license-file: LICENSE+build-type: Simple+extra-source-files:+ cbits/kb_text_shape.c+ cbits/kb_text_shape.h+ cbits/kb_text_shape.inc+extra-doc-files:+ README.md+ CHANGELOG.md++source-repository head+ type: git+ location: https://github.com/dpwiz/kb-text-shape++flag trace-blocks+ manual: True+ default: False++library+ exposed-modules:+ KB.Text.Shape+ KB.Text.Shape.FFI.Allocator+ KB.Text.Shape.FFI.API.Context+ KB.Text.Shape.FFI.API.Direct+ KB.Text.Shape.FFI.API.Other+ KB.Text.Shape.FFI.API.Segmentation+ KB.Text.Shape.FFI.Enums+ KB.Text.Shape.FFI.Enums.FeatureTag+ KB.Text.Shape.FFI.Enums.Language+ KB.Text.Shape.FFI.Enums.Script+ KB.Text.Shape.FFI.Flags+ KB.Text.Shape.FFI.Handles+ KB.Text.Shape.FFI.Iterators+ KB.Text.Shape.FFI.Structs+ KB.Text.Shape.Font+ other-modules:+ Paths_kb_text_shape+ autogen-modules:+ Paths_kb_text_shape+ hs-source-dirs:+ src+ default-extensions:+ BlockArguments+ DataKinds+ DerivingStrategies+ DuplicateRecordFields+ GeneralizedNewtypeDeriving+ ImplicitParams+ LambdaCase+ NamedFieldPuns+ NoFieldSelectors+ NoFieldSelectors+ OverloadedRecordDot+ OverloadedStrings+ PatternSynonyms+ RecordWildCards+ StrictData+ ViewPatterns+ ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-home-modules -Wredundant-constraints+ cc-options: -Wno-return-local-addr+ include-dirs:+ cbits+ c-sources:+ cbits/kb_text_shape.c+ build-depends:+ base >=4.16 && <5+ , bytestring+ , containers+ , text+ default-language: GHC2021+ if flag(trace-blocks)+ cc-options: -DTRACE_BLOCKS++test-suite kb-text-shape-test+ type: exitcode-stdio-1.0+ main-is: Spec.hs+ other-modules:+ Paths_kb_text_shape+ autogen-modules:+ Paths_kb_text_shape+ hs-source-dirs:+ test+ default-extensions:+ BlockArguments+ DataKinds+ DerivingStrategies+ DuplicateRecordFields+ GeneralizedNewtypeDeriving+ ImplicitParams+ LambdaCase+ NamedFieldPuns+ NoFieldSelectors+ NoFieldSelectors+ OverloadedRecordDot+ OverloadedStrings+ PatternSynonyms+ RecordWildCards+ StrictData+ ViewPatterns+ ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-home-modules -Wredundant-constraints -threaded -rtsopts -with-rtsopts=-N+ build-depends:+ base >=4.16 && <5+ , bytestring+ , kb-text-shape+ , text+ default-language: GHC2021++benchmark kb-text-shape-bench+ type: exitcode-stdio-1.0+ main-is: Bench.hs+ other-modules:+ Paths_kb_text_shape+ autogen-modules:+ Paths_kb_text_shape+ hs-source-dirs:+ bench+ default-extensions:+ BlockArguments+ DataKinds+ DerivingStrategies+ DuplicateRecordFields+ GeneralizedNewtypeDeriving+ ImplicitParams+ LambdaCase+ NamedFieldPuns+ NoFieldSelectors+ NoFieldSelectors+ OverloadedRecordDot+ OverloadedStrings+ PatternSynonyms+ RecordWildCards+ StrictData+ ViewPatterns+ ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-home-modules -Wredundant-constraints -threaded -rtsopts -with-rtsopts=-N+ build-depends:+ base >=4.16 && <5+ , bytestring+ , kb-text-shape+ , text+ , unliftio+ default-language: GHC2021
+ src/KB/Text/Shape.hs view
@@ -0,0 +1,322 @@+module KB.Text.Shape+ ( -- * The slow part+ withContext+ , Context(..)+ , createContext+ , destroyContext++ -- ** Adding fonts+ -- $stack+ , Handles.Font+ , pushFontFromFile+ , pushFontFromMemory+ , pushFont+ , popFont++ -- * Turning texts into glyphs+ , run+ , Run(..)+ , Glyph(..)+ , gpos+ , GPOS(..)+ -- ** Feeding input+ , text_+ , char_+ -- $features+ , withFeature_+ , pushFeature_+ , popFeature_+ -- * Internals+ , stripGlyph+ ) where++import Control.Monad+import Data.IORef+import Foreign+import Foreign.C+import Prelude hiding (id)++import Control.Exception (bracket)+import Data.ByteString (ByteString)+import Data.ByteString.Unsafe qualified as ByteString+import Data.Char (chr, ord)+import Data.IntMap (IntMap)+import Data.IntMap.Strict qualified as IntMap+import Data.Text (Text)+import Data.Text.Foreign qualified as Text+import GHC.Records (HasField(..))++import KB.Text.Shape.FFI.API.Context qualified as ShapeContext+import KB.Text.Shape.FFI.Enums qualified as Enums+import KB.Text.Shape.FFI.Flags qualified as Flags+import KB.Text.Shape.FFI.Handles qualified as Handles+import KB.Text.Shape.FFI.Iterators qualified as Iterators+import KB.Text.Shape.FFI.Structs qualified as Structs++withContext :: (Context -> IO r) -> IO r+withContext = bracket createContext destroyContext++data Context = Context+ { handle :: Handles.ShapeContext+ , fonts :: IORef (IntMap ByteStringRC)+ }++data ByteStringRC = ByteStringRC ByteString Int++createContext :: IO Context+createContext = do+ handle <- ShapeContext.kbts_CreateShapeContext nullFunPtr nullPtr+ when (handle == Handles.ShapeContext nullPtr) $+ -- XXX: assuming the default allocator didn't allocate anything yet+ error "kbts_CreateShapeContext: failed to init"+ fonts <- newIORef mempty+ pure Context{handle, fonts}++destroyContext :: Context -> IO ()+destroyContext Context{handle} = ShapeContext.kbts_DestroyShapeContext handle++{- $stack++The context is capable of managing multiple fonts through a font stack.+The font stack will hold references to all fonts in use by the context. Whenever+you try to shape some text, the context will check to see if it is supported by+the font at the top of the stack. If it is not, it will try the next font down,+and so on, until all fonts have been tried. As such, you should push your fallback+fonts first, and your preferred fonts last.++-}++pushFontFromFile :: Context -> FilePath -> Int -> IO Handles.Font+pushFontFromFile ctx path fontIndex = do+ font <- withCString path \pathPtr ->+ ShapeContext.kbts_ShapePushFontFromFile ctx.handle pathPtr (fromIntegral fontIndex)+ let err = ShapeContext.kbts_ShapeError ctx.handle+ when (err /= Enums.SHAPE_ERROR_NONE) $+ error $ "kbts_ShapePushFontFromFile: failed to load font. " <> show err+ _ <- keepFont ctx font mempty -- register the empty blob so the counters would look nicer+ pure font++pushFontFromMemory :: Context -> ByteString -> Int -> IO Handles.Font+pushFontFromMemory ctx fontData fontIndex =+ ByteString.unsafeUseAsCStringLen fontData \(memoryPtr, memorySize) -> do+ font <- ShapeContext.kbts_ShapePushFontFromMemory ctx.handle (castPtr memoryPtr) (fromIntegral memorySize) (fromIntegral fontIndex)+ let err = ShapeContext.kbts_ShapeError ctx.handle+ when (err /= Enums.SHAPE_ERROR_NONE) $+ error $ "kbts_ShapePushFontFromMemory: failed to load font. " <> show err+ _ <- keepFont ctx font fontData+ pure font++keepFont :: Context -> Handles.Font -> ByteString -> IO Int+keepFont ctx font bytes = atomicModifyIORef' ctx.fonts $ swap . IntMap.alterF addRef (Handles.intHandle font)+ where+ swap (a, b) = (b, a)+ addRef :: Maybe ByteStringRC -> (Int, Maybe ByteStringRC)+ addRef = \case+ Nothing -> (1, Just $ ByteStringRC bytes 1)+ Just (ByteStringRC oldBytes oldC) -> (newC, Just $ ByteStringRC oldBytes newC)+ where+ newC = oldC + 1++releaseFont :: Context -> Handles.Font -> IO Int+releaseFont ctx font = atomicModifyIORef' ctx.fonts $ swap . IntMap.alterF delRef (Handles.intHandle font)+ where+ swap (a, b) = (b, a)+ delRef :: Maybe ByteStringRC -> (Int, Maybe ByteStringRC)+ delRef = \case+ Nothing -> (-1, Nothing)+ Just (ByteStringRC _old 1) -> (0, Nothing)+ Just (ByteStringRC stillUsed oldC) -> (newC, Just $ ByteStringRC stillUsed newC)+ where newC = oldC - 1++pushFont :: Context -> Handles.Font -> IO Int+pushFont ctx font = do+ font' <- ShapeContext.kbts_ShapePushFont ctx.handle font+ keepFont ctx font' mempty++popFont :: Context -> IO (Int, Handles.Font)+popFont ctx = do+ font <- ShapeContext.kbts_ShapePopFont ctx.handle+ kept <- releaseFont ctx font+ pure (kept, font)++{- | Run the segmentation and shaping.++NB: Make sure you did load some fonts and text data!++Add content with 'text_' and 'char_', which you may wrap in feature tag sections.+-}+run :: Context -> ((?shapeContext :: Handles.ShapeContext) => IO ()) -> IO [(Run, [Glyph])]+run ctx action = do+ ShapeContext.kbts_ShapeBegin ctx.handle Enums.DIRECTION_DONT_KNOW Enums.LANGUAGE_DONT_KNOW+ shapeAction+ ShapeContext.kbts_ShapeEnd ctx.handle++ iterateRun ctx+ where+ shapeAction = let ?shapeContext = ctx.handle in action++-- | Add one codepoint to the shaping run.+char_ :: (?shapeContext :: Handles.ShapeContext) => Char -> IO ()+char_ c = ShapeContext.kbts_ShapeCodepoint ?shapeContext (fromIntegral (ord c))++{- | Add a chunk of text to the shaping run.++This will not add extra characters like newlines or whitespace.+You may want to call this multiple times instead of concatentating everything.+-}+text_ :: (?shapeContext :: Handles.ShapeContext) => Text -> IO ()+text_ t =+ Text.withCStringLen t \(strPtr, strLen) ->+ ShapeContext.kbts_ShapeUtf8+ ?shapeContext+ strPtr+ (fromIntegral strLen)+ Enums.USER_ID_GENERATION_MODE_CODEPOINT_INDEX++{- $features++The context has a feature stack that allows you to manipulate font features hierarchically.+When you give text to the context, it will apply all feature overrides that are on the+stack at the time.++If two feature overrides use the same tag, then only the latest one, i.e. the one higher+in the stack, is applied.+-}++withFeature_ :: (?shapeContext :: Handles.ShapeContext) => Enums.FeatureTag -> Int -> IO r -> IO r+withFeature_ tag value action = do+ ShapeContext.kbts_ShapePushFeature ?shapeContext tag (fromIntegral value)+ r <- action+ _ <- ShapeContext.kbts_ShapePopFeature ?shapeContext tag+ pure r++pushFeature_ :: (?shapeContext :: Handles.ShapeContext) => Enums.FeatureTag -> Int -> IO ()+pushFeature_ tag value = ShapeContext.kbts_ShapePushFeature ?shapeContext tag (fromIntegral value)++popFeature_ :: (?shapeContext :: Handles.ShapeContext) => Enums.FeatureTag -> IO Int+popFeature_ tag = fromIntegral <$> ShapeContext.kbts_ShapePopFeature ?shapeContext tag++{- | Text runs with uniform direction and script.++The result of a text segmentation work.+-}+data Run = Run+ { font :: Handles.Font+ , script :: Enums.Script+ , paragraphDirection :: Enums.Direction+ , direction :: Enums.Direction+ , flags :: Flags.BreakFlags+ } deriving (Eq, Show)++iterateRun :: Context -> IO [(Run, [Glyph])]+iterateRun ctx =+ alloca \runPtr ->+ alloca \glyphOutPtr ->+ stepWhile (step runPtr) (collect runPtr glyphOutPtr)+ where+ step runPtr = (/= 0) <$> ShapeContext.kbts_ShapeRun ctx.handle runPtr+ collect runPtr glyphOutPtr = do+ Structs.Run{..} <- peek runPtr+ (Run{..},) <$> iterateGlyphs glyphOutPtr (Structs.runGlyphIterator runPtr)++iterateGlyphs :: Ptr (Ptr Structs.Glyph) -> Ptr Structs.GlyphIterator -> IO [Glyph]+iterateGlyphs glyphOutPtr it = stepWhile step fetch+ where+ step = (/= 0) <$> Iterators.kbts_GlyphIteratorNext it glyphOutPtr+ fetch = do+ peek glyphOutPtr >>= peek >>= stripGlyph++stepWhile :: Monad m => m Bool -> m a -> m [a]+stepWhile step fetch = do+ result <- step+ if result then do+ x <- fetch+ (x :) <$> stepWhile step fetch+ else+ pure []++{- | Glyphs ready to rasterize.++The result of a text shaping work.+-}+data Glyph = Glyph+ { -- omitted: prev :: Ptr Glyph+ -- omitted: next :: Ptr Glyph+ codepoint :: Char -- was: Word32+ , id :: Word16 -- ^ Glyph index. This is what you want to use to query outline data.+ , uid :: Word16++ , codepointIndex :: Int -- was: userIdOrCodepointIndex++ , offsetX :: Int+ {- ^ This, and the next few are in the "font units".+ Those have to be scaled appropriately using font metrics.+ To get the consistent results when using multiple fonts divide by 'KB.Text.Shape.Font.capHeight',+ then scale to the desired height.+ -}+ , offsetY :: Int+ , advanceX :: Int+ , advanceY :: Int++ , attachGlyph :: Maybe Glyph -- was: Ptr Glyph++ -- omitted: config :: Ptr () -- kbts_glyph_config *Config;++ , decomposition :: Word64++ , classes :: Word32 -- kbts_glyph_classes Classes;+ , flags :: Flags.GlyphFlags+ -- omitted: parentInfo :: Word32++ -- omitted: ligatureUid :: Word16+ -- omitted: ligatureComponentIndexPlusOne :: Word16+ -- omitted: ligatureComponentCount :: Word16++ -- omitted: joiningFeature :: Word8 -- kbts_joining_feature JoiningFeature;++ -- Unicode properties filled in by CodepointToGlyph.+ , joiningType :: Enums.UnicodeJoiningType+ , unicodeFlags :: Word8+ , syllabicClass :: Word8+ , syllabicPosition :: Word8+ , useClass :: Word8+ , combiningClass :: Word8+ }+ deriving (Eq, Show)++instance HasField "gpos" Glyph (GPOS Int) where+ {-# INLINE getField #-}+ getField = gpos++-- | Extract glyph positioning information.+{-# INLINE gpos #-}+gpos :: Glyph -> GPOS Int+gpos Glyph{offsetX, offsetY, advanceX, advanceY} = GPOS{offsetX, offsetY, advanceX, advanceY}++{- | A container for glyph positioning information.++You may want to use its Functor instance to convert between different units.+-}+data GPOS a = GPOS+ { offsetX, offsetY, advanceX, advanceY :: a+ }+ deriving (Eq, Show, Functor)++-- | Remove the internals and pointer data+stripGlyph :: Structs.Glyph -> IO Glyph+stripGlyph Structs.Glyph{..} = do+ attached <-+ if attachGlyph == nullPtr then+ pure Nothing+ else+ Just <$> (peek attachGlyph >>= stripGlyph)+ pure Glyph+ { codepoint = chr (fromIntegral codepoint)+ , codepointIndex = userIdOrCodepointIndex -- XXX: always codepoint when using context api+ , attachGlyph = attached+ , offsetX = fromIntegral offsetX+ , offsetY = fromIntegral offsetY+ , advanceX = fromIntegral advanceX+ , advanceY = fromIntegral advanceY+ , ..+ }
+ src/KB/Text/Shape/FFI/API/Context.hsc view
@@ -0,0 +1,201 @@+module KB.Text.Shape.FFI.API.Context where++import Prelude hiding (id, error)++import Foreign+import Foreign.C++import KB.Text.Shape.FFI.Allocator (Allocator)+import KB.Text.Shape.FFI.Handles+import KB.Text.Shape.FFI.Enums+import KB.Text.Shape.FFI.Structs++#include "kb_text_shape.h"++-- The context can do everything for you. It is pretty convenient!++-- | @int kbts_SizeOfShapeContext(void);@+foreign import ccall unsafe "kbts_SizeOfShapeContext" kbts_SizeOfShapeContext :: CInt++-- | @kbts_shape_context *kbts_PlaceShapeContext(kbts_allocator_function *Allocator, void *AllocatorData, void *Memory);@+foreign import ccall safe "kbts_PlaceShapeContext" kbts_PlaceShapeContext+ :: FunPtr Allocator+ -> Ptr () -- ^ AllocatorData+ -> Ptr () -- ^ Memory+ -> IO ShapeContext++-- | @kbts_shape_context *kbts_PlaceShapeContextFixedMemory(void *Memory, int Size);@+foreign import ccall unsafe "kbts_PlaceShapeContextFixedMemory" kbts_PlaceShapeContextFixedMemory+ :: Ptr () -- ^ Memory+ -> CInt -- ^ Size+ -> IO ShapeContext -- ^ kbts_shape_context *++-- | @kbts_shape_context *kbts_CreateShapeContext(kbts_allocator_function *Allocator, void *AllocatorData);@+foreign import ccall safe "kbts_CreateShapeContext" kbts_CreateShapeContext+ :: FunPtr Allocator+ -> Ptr () -- ^ AllocatorData+ -> IO ShapeContext++-- | @void kbts_DestroyShapeContext(kbts_shape_context *Context);@+foreign import ccall unsafe "kbts_DestroyShapeContext" kbts_DestroyShapeContext+ :: ShapeContext+ -> IO ()++#ifndef KB_TEXT_SHAPE_NO_CRT+-- | @kbts_font *kbts_ShapePushFontFromFile(kbts_shape_context *Context, const char *FileName, int FontIndex);@+foreign import ccall unsafe "kbts_ShapePushFontFromFile" kbts_ShapePushFontFromFile+ :: ShapeContext+ -> CString -- ^ FileName+ -> CInt -- ^ FontIndex+ -> IO Font+#endif++-- | @kbts_font *kbts_ShapePushFontFromMemory(kbts_shape_context *Context, void *Memory, int Size, int FontIndex);@+foreign import ccall unsafe "kbts_ShapePushFontFromMemory" kbts_ShapePushFontFromMemory+ :: ShapeContext+ -> Ptr () -- ^ Memory+ -> CSize -- ^ Size+ -> CInt -- ^ FontIndex+ -> IO Font++-- | @kbts_font *kbts_ShapePushFont(kbts_shape_context *Context, kbts_font *Font);@+foreign import ccall unsafe "kbts_ShapePushFont" kbts_ShapePushFont+ :: ShapeContext+ -> Font+ -> IO Font++-- | @kbts_font *kbts_ShapePopFont(kbts_shape_context *Context);@+foreign import ccall unsafe "kbts_ShapePopFont" kbts_ShapePopFont+ :: ShapeContext+ -> IO Font++-- | @void kbts_ShapeBegin(kbts_shape_context *Context, kbts_direction ParagraphDirection, kbts_language Language);@+foreign import ccall unsafe "kbts_ShapeBegin" kbts_ShapeBegin+ :: ShapeContext+ -> Direction+ -> Language+ -> IO ()++-- @void kbts_ShapeEnd(kbts_shape_context *Context);@+foreign import ccall unsafe "kbts_ShapeEnd" kbts_ShapeEnd+ :: ShapeContext+ -> IO ()++-- | @int kbts_ShapeRun(kbts_shape_context *Context, kbts_run *Run);@+foreign import ccall unsafe "kbts_ShapeRun" kbts_ShapeRun+ :: ShapeContext+ -> Ptr Run+ -> IO Int++-- | @void kbts_ShapePushFeature(kbts_shape_context *Context, kbts_u32 FeatureTag, int Value);@+foreign import ccall unsafe "kbts_ShapePushFeature" kbts_ShapePushFeature+ :: ShapeContext+ -> FeatureTag+ -> CInt -- ^ Value+ -> IO ()++-- | @int kbts_ShapePopFeature(kbts_shape_context *Context, kbts_u32 FeatureTag);@+foreign import ccall unsafe "kbts_ShapePopFeature" kbts_ShapePopFeature+ :: ShapeContext+ -> FeatureTag+ -> IO CInt++-- | @void kbts_ShapeCodepoint(kbts_shape_context *Context, int Codepoint);@+foreign import ccall unsafe "kbts_ShapeCodepoint" kbts_ShapeCodepoint+ :: ShapeContext+ -> CInt -- ^ Codepoint+ -> IO ()++-- | @void kbts_ShapeCodepointWithUserId(kbts_shape_context *Context, int Codepoint, int UserId);@+foreign import ccall unsafe "kbts_ShapeCodepointWithUserId" kbts_ShapeCodepointWithUserId+ :: ShapeContext+ -> CInt -- ^ Codepoint+ -> CInt -- ^ UserId+ -> IO ()++-- | @void kbts_ShapeUtf32(kbts_shape_context *Context, int *Utf32, int Length);@+foreign import ccall unsafe "kbts_ShapeUtf32" kbts_ShapeUtf32+ :: ShapeContext+ -> Ptr CInt -- ^ Utf32+ -> CInt -- ^ Length+ -> IO ()++-- | @void kbts_ShapeUtf32WithUserId(kbts_shape_context *Context, int *Utf32, int Length, int UserId, int UserIdIncrement);@+foreign import ccall unsafe "kbts_ShapeUtf32WithUserId" kbts_ShapeUtf32WithUserId+ :: ShapeContext+ -> Ptr CInt -- ^ Utf32+ -> CInt -- ^ Length+ -> CInt -- ^ UserId+ -> CInt -- ^ UserIdIncrement+ -> IO ()++-- | @void kbts_ShapeUtf8(kbts_shape_context *Context, const char *Utf8, int Length, kbts_user_id_generation_mode UserIdGenerationMode);@+foreign import ccall unsafe "kbts_ShapeUtf8" kbts_ShapeUtf8+ :: ShapeContext+ -> Ptr CChar+ -> CInt -- ^ Length+ -> UserIdGenerationMode+ -> IO ()++-- | @void kbts_ShapeUtf8WithUserId(kbts_shape_context *Context, const char *Utf8, int Length, int UserId, kbts_user_id_generation_mode UserIdGenerationMode);@+foreign import ccall unsafe "kbts_ShapeUtf8WithUserId" kbts_ShapeUtf8WithUserId+ :: ShapeContext+ -> Ptr CChar+ -> CInt -- ^ Length+ -> CInt -- ^ UserId+ -> UserIdGenerationMode+ -> IO ()++-- | @kbts_shape_error kbts_ShapeError(kbts_shape_context *Context);@+foreign import ccall unsafe "kbts_ShapeError" kbts_ShapeError+ :: ShapeContext+ -> ShapeError++-- | @void kbts_ShapeBeginManualRuns(kbts_shape_context *Context);@+foreign import ccall unsafe "kbts_ShapeBeginManualRuns" kbts_ShapeBeginManualRuns+ :: ShapeContext+ -> IO ()++-- | @void kbts_ShapeNextManualRun(kbts_shape_context *Context, kbts_direction Direction, kbts_script Script);@+foreign import ccall unsafe "kbts_ShapeNextManualRun" kbts_ShapeNextManualRun+ :: ShapeContext+ -> Direction+ -> Script+ -> IO ()++-- | @void kbts_ShapeEndManualRuns(kbts_shape_context *Context);@+foreign import ccall unsafe "kbts_ShapeEndManualRuns" kbts_ShapeEndManualRuns+ :: ShapeContext+ -> IO ()++-- | @void kbts_ShapeManualBreak(kbts_shape_context *Context);@+foreign import ccall unsafe "kbts_ShapeManualBreak" kbts_ShapeManualBreak+ :: ShapeContext+ -> IO ()++-- | Wrapped @kbts_shape_codepoint_iterator kbts_ShapeCurrentCodepointsIterator(kbts_shape_context *Context);@+--+-- The original returns struct by value.+foreign import ccall unsafe "hs_ShapeCurrentCodepointsIterator" hs_ShapeCurrentCodepointsIterator+ :: ShapeContext+ -> Ptr CodepointIterator+ -> IO ()++-- | @int kbts_ShapeCodepointIteratorIsValid(kbts_shape_codepoint_iterator *It);@+foreign import ccall unsafe "kbts_ShapeCodepointIteratorIsValid" kbts_ShapeCodepointIteratorIsValid+ :: Ptr CodepointIterator+ -> IO Int++-- | @int kbts_ShapeCodepointIteratorNext(kbts_shape_codepoint_iterator *It, kbts_shape_codepoint *Codepoint, int *CodepointIndex);@+foreign import ccall unsafe "kbts_ShapeCodepointIteratorNext" kbts_ShapeCodepointIteratorNext+ :: Ptr CodepointIterator+ -> Ptr Codepoint+ -> Ptr Int+ -> IO Int++-- | @int kbts_ShapeGetShapeCodepoint(kbts_shape_context *Context, int CodepointIndex, kbts_shape_codepoint *Codepoint);@+foreign import ccall unsafe "kbts_ShapeGetShapeCodepoint" kbts_ShapeGetShapeCodepoint+ :: ShapeContext+ -> CInt -- ^ CodepointIndex+ -> Ptr Codepoint+ -> IO Int
+ src/KB/Text/Shape/FFI/API/Direct.hsc view
@@ -0,0 +1,243 @@+module KB.Text.Shape.FFI.API.Direct where++import Prelude hiding (id, error)++import Foreign+import Foreign.C++import KB.Text.Shape.FFI.Allocator (Allocator)+import KB.Text.Shape.FFI.Handles+import KB.Text.Shape.FFI.Enums+import KB.Text.Shape.FFI.Structs++#include "kb_text_shape.h"++-- | @kbts_shape_error kbts_ShapeDirect(kbts_shape_config *Config, kbts_glyph_storage *Storage, kbts_direction RunDirection, kbts_allocator_function *Allocator, void *AllocatorData, kbts_glyph_iterator *Output);@+foreign import ccall safe "kbts_ShapeDirect" kbts_ShapeDirect+ :: ShapeConfig+ -> Ptr GlyphStorage+ -> Direction+ -> FunPtr Allocator+ -> Ptr ()+ -> Ptr GlyphIterator+ -> IO ShapeError++-- | @kbts_shape_error kbts_ShapeDirectFixedMemory(kbts_shape_config *Config, kbts_glyph_storage *Storage, kbts_direction RunDirection, void *Memory, int MemorySize, kbts_glyph_iterator *Output);@+foreign import ccall unsafe "kbts_ShapeDirectFixedMemory" kbts_ShapeDirectFixedMemory+ :: ShapeConfig+ -> Ptr GlyphStorage+ -> Direction -- ^ RunDirection+ -> Ptr () -- ^ Memory+ -> CInt -- ^ MemorySize+ -> IO ShapeError++-- A font holds all data that corresponds to a given font file.++#ifndef KB_TEXT_SHAPE_NO_CRT+-- | @kbts_font kbts_FontFromFile(const char *FileName, int FontIndex, kbts_allocator_function *Allocator, void *AllocatorData, void **FileData, int *FileSize);@+foreign import ccall safe "hs_FontFromFile" hs_FontFromFile+ :: Ptr CChar -- ^ FileName+ -> CInt -- ^ FontIndex+ -> FunPtr Allocator+ -> Ptr () -- ^ AllocatorData+ -> Ptr (Ptr ()) -- ^ FileData+ -> Ptr CInt -- ^ FileSize+ -> Ptr Font+ -> IO LoadFontError+#endif++-- | @int kbts_FontCount(void *FileData, int FileSize);@+foreign import ccall unsafe "kbts_FontCount" kbts_FontCount+ :: Ptr () -- ^ FileData+ -> CInt -- ^ FileSize+ -> CInt++-- | @kbts_font kbts_FontFromMemory(void *FileData, int FileSize, int FontIndex, kbts_allocator_function *Allocator, void *AllocatorData);@+foreign import ccall safe "hs_FontFromMemory" hs_FontFromMemory+ :: Ptr () -- ^ FileData+ -> CInt -- ^ FileSize+ -> CInt -- ^ FontIndex+ -> FunPtr Allocator+ -> Ptr () -- ^ AllocatorData+ -> Font+ -> IO LoadFontError++-- | @void kbts_FreeFont(kbts_font *Font);@+foreign import ccall safe "kbts_FreeFont" kbts_FreeFont+ :: Font+ -> IO ()++-- | @int kbts_FontIsValid(kbts_font *Font);@+foreign import ccall unsafe "kbts_FontIsValid" kbts_FontIsValid+ :: Font+ -> CInt++-- | Opaque token for @kbts_load_font_state@+data LoadFontState = LoadFontState -- XXX: neither a struct, nor a handle+{-+ void *FontData;+ kbts_u32 FontDataSize;++ kbts_blob_table Tables[KBTS_BLOB_TABLE_ID_COUNT];+ kbts_u32 LookupCount;+ kbts_u32 LookupSubtableCount;+ kbts_u32 GlyphCount;+ kbts_u32 ScratchSize;++ kbts_u32 GlyphLookupMatrixSizeInBytes;+ kbts_u32 GlyphLookupSubtableMatrixSizeInBytes;+ kbts_u32 TotalSize;+-}+ deriving (Show)++instance Storable LoadFontState where+ alignment ~_ = #alignment kbts_load_font_state+ sizeOf ~_ = #size kbts_load_font_state+ peek _ptr = pure LoadFontState+ poke ptr LoadFontState{} = fillBytes ptr 0x00 (#size kbts_load_font_state)++-- | @kbts_load_font_error kbts_LoadFont(kbts_font *Font, kbts_load_font_state *State, void *FontData, int FontDataSize, int FontIndex, int *ScratchSize_, int *OutputSize_);@+foreign import ccall unsafe "kbts_LoadFont" kbts_LoadFont+ :: Font+ -> Ptr LoadFontState+ -> Ptr () -- ^ FontData+ -> CInt -- ^ FontDataSize+ -> CInt -- ^ FontIndex+ -> Ptr Int -- ^ ScratchSize_+ -> Ptr Int -- ^ OutputSize_+ -> IO LoadFontError++-- | @kbts_load_font_error kbts_PlaceBlob(kbts_font *Font, kbts_load_font_state *State, void *ScratchMemory, void *OutputMemory);@+foreign import ccall unsafe "kbts_PlaceBlob" kbts_PlaceBlob+ :: Font+ -> Ptr LoadFontState+ -> Ptr () -- ^ ScratchMemory+ -> Ptr () -- ^ OutputMemory+ -> IO LoadFontError++-- | @void kbts_GetFontInfo(kbts_font *Font, kbts_font_info *Info);@+foreign import ccall unsafe "kbts_GetFontInfo" kbts_GetFontInfo+ :: Font+ -> Ptr FontInfo+ -> IO ()++-- A shape_config is a bag of pre-computed data for a specific shaping setup.++-- | @int kbts_SizeOfShapeConfig(kbts_font *Font, kbts_script Script, kbts_language Language);@+foreign import ccall unsafe "kbts_SizeOfShapeConfig" kbts_SizeOfShapeConfig+ :: Font+ -> Script+ -> Language+ -> CInt++-- | @kbts_shape_config *kbts_PlaceShapeConfig(kbts_font *Font, kbts_script Script, kbts_language Language, void *Memory);@+foreign import ccall unsafe "kbts_PlaceShapeConfig" kbts_PlaceShapeConfig+ :: Font+ -> Script+ -> Language+ -> Ptr () -- ^ Memory+ -> IO ShapeConfig++-- | @kbts_shape_config *kbts_CreateShapeConfig(kbts_font *Font, kbts_script Script, kbts_language Language, kbts_allocator_function *Allocator, void *AllocatorData);@+foreign import ccall unsafe "kbts_CreateShapeConfig" kbts_CreateShapeConfig+ :: Font+ -> Script+ -> Language+ -> FunPtr Allocator+ -> Ptr ()+ -> IO ShapeConfig++-- | @void kbts_DestroyShapeConfig(kbts_shape_config *Config);@+foreign import ccall unsafe "kbts_DestroyShapeConfig" kbts_DestroyShapeConfig+ :: ShapeConfig+ -> IO ()++-- A glyph_storage holds and recycles glyph data.++-- | @int kbts_InitializeGlyphStorage(kbts_glyph_storage *Storage, kbts_allocator_function *Allocator, void *AllocatorData)@+foreign import ccall unsafe "kbts_InitializeGlyphStorage" kbts_InitializeGlyphStorage+ :: Ptr GlyphStorage+ -> FunPtr Allocator+ -> Ptr () -- ^ AllocatorData+ -> IO Int++-- | @int kbts_InitializeGlyphStorageFixedMemory(kbts_glyph_storage *Storage, void *Memory, int MemorySize);@+foreign import ccall unsafe "kbts_InitializeGlyphStorageFixedMemory" kbts_InitializeGlyphStorageFixedMemory+ :: Ptr GlyphStorage+ -> Ptr () -- ^ Memory+ -> CInt -- ^ MemorySize+ -> IO Int++-- | @kbts_glyph *kbts_PushGlyph(kbts_glyph_storage *Storage, kbts_font *Font, int Codepoint, kbts_glyph_config *Config, int UserId);@+foreign import ccall unsafe "kbts_PushGlyph" kbts_PushGlyph+ :: Ptr GlyphStorage+ -> Font+ -> CInt -- ^ Codepoint+ -> GlyphConfig+ -> CInt+ -> IO (Ptr Glyph)++-- | @void kbts_ClearActiveGlyphs(kbts_glyph_storage *Storage);@+foreign import ccall unsafe "kbts_ClearActiveGlyphs" kbts_ClearActiveGlyphs+ :: Ptr GlyphStorage+ -> IO ()++-- | @void kbts_FreeAllGlyphs(kbts_glyph_storage *Storage);@+foreign import ccall unsafe "kbts_FreeAllGlyphs" kbts_FreeAllGlyphs+ :: Ptr GlyphStorage+ -> IO ()++-- | Wrapped @kbts_glyph kbts_CodepointToGlyph(kbts_font *Font, int Codepoint, kbts_glyph_config *Config, int UserId);@+--+-- The original returns struct by value.+foreign import ccall unsafe "hs_CodepointToGlyph" hs_CodepointToGlyph+ :: Font+ -> CInt -- ^ Codepoint+ -> GlyphConfig+ -> CInt -- ^ UserId+ -> Ptr Glyph+ -> IO ()++-- | @int kbts_CodepointToGlyphId(kbts_font *Font, int Codepoint);@+foreign import ccall unsafe "kbts_CodepointToGlyphId" kbts_CodepointToGlyphId+ :: Font+ -> CInt -- ^ Codepoint+ -> IO Int++-- | Wrapped @kbts_glyph_iterator kbts_ActiveGlyphIterator(kbts_glyph_storage *Storage);@+--+-- The original returns struct by value.+foreign import ccall unsafe "hs_ActiveGlyphIterator" hs_ActiveGlyphIterator+ :: Ptr GlyphStorage+ -> Ptr GlyphIterator+ -> IO ()++-- A glyph_config specifies glyph-specific shaping parameters.+--+-- A single glyph_config can be shared by multiple glyphs.++-- | @int kbts_SizeOfGlyphConfig(kbts_feature_override *Overrides, int OverrideCount);@+foreign import ccall unsafe "kbts_SizeOfGlyphConfig" kbts_SizeOfGlyphConfig+ :: Ptr FeatureOverride+ -> CInt -- ^ OverrideCount+ -> CInt++-- | @kbts_glyph_config *kbts_PlaceGlyphConfig(kbts_feature_override *Overrides, int OverrideCount, void *Memory);@+foreign import ccall unsafe "kbts_PlaceGlyphConfig" kbts_PlaceGlyphConfig+ :: Ptr FeatureOverride+ -> CInt -- ^ OverriderCount+ -> Ptr () -- ^ Memory+ -> IO GlyphConfig++-- | @kbts_glyph_config *kbts_CreateGlyphConfig(kbts_feature_override *Overrides, int OverrideCount, kbts_allocator_function *Allocator, void *AllocatorData);@+foreign import ccall safe "kbts_CreateGlyphConfig" kbts_CreateGlyphConfig+ :: Ptr FeatureOverride+ -> CInt -- ^ OverrideCount+ -> FunPtr Allocator+ -> Ptr () -- ^ AllocatorData+ -> IO GlyphConfig++-- | @void kbts_DestroyGlyphConfig(kbts_glyph_config *Config);@+foreign import ccall unsafe "kbts_DestroyGlyphConfig" kbts_DestroyGlyphConfig+ :: GlyphConfig+ -> IO ()
+ src/KB/Text/Shape/FFI/API/Other.hsc view
@@ -0,0 +1,65 @@+module KB.Text.Shape.FFI.API.Other where++import Prelude hiding (id, error)++import Foreign+import Foreign.C++import KB.Text.Shape.FFI.Handles+import KB.Text.Shape.FFI.Enums+import KB.Text.Shape.FFI.Structs++#include "kb_text_shape.h"++-- ** Quick test for font support of a sequence of codepoints.++-- | @void kbts_FontCoverageTestBegin(kbts_font_coverage_test *Test, kbts_font *Font);@+foreign import ccall "kbts_FontCoverageTestBegin" kbts_FontCoverageTestBegin+ :: Ptr FontCoverageTest+ -> Font+ -> IO ()++-- | @void kbts_FontCoverageTestCodepoint(kbts_font_coverage_test *Test, int Codepoint);@+foreign import ccall "kbts_FontCoverageTestCodepoint" kbts_FontCoverageTestCodepoint+ :: Ptr FontCoverageTest+ -> CInt -- ^ Codepoint+ -> IO ()++-- | @int kbts_FontCoverageTestEnd(kbts_font_coverage_test *Test);@+foreign import ccall "kbts_FontCoverageTestEnd" kbts_FontCoverageTestEnd+ :: Ptr FontCoverageTest+ -> IO Int++-- ** Misc.++-- | @kbts_decode kbts_DecodeUtf8(const char *Utf8, kbts_un Length);@++-- | @kbts_encode_utf8 kbts_EncodeUtf8(int Codepoint);@++foreign import ccall unsafe "kbts_ScriptDirection" kbts_ScriptDirection+ :: Script+ -> Direction++-- | @int kbts_ScriptIsComplex(kbts_script Script);@+foreign import ccall unsafe "kbts_ScriptIsComplex" kbts_ScriptIsComplex+ :: Script+ -> CInt++newtype ScriptTag = ScriptTag Word32+ deriving (Eq, Ord, Show)+ deriving newtype (Storable)++-- | @kbts_script kbts_ScriptTagToScript(kbts_script_tag Tag);@+foreign import ccall unsafe "kbts_ScriptTagToScript" kbts_ScriptTagToScript+ :: ScriptTag+ -> Script++-- define KBTS_FOURCC(A, B, C, D) ((A) | ((B) << 8) | ((C) << 16) | ((D) << 24))++foreign import ccall unsafe "hs_GetUnitsPerEm" hs_GetUnitsPerEm+ :: Font+ -> Word16++foreign import ccall unsafe "hs_GetCapHeight" hs_GetCapHeight+ :: Font+ -> Word16
+ src/KB/Text/Shape/FFI/API/Segmentation.hsc view
@@ -0,0 +1,111 @@+module KB.Text.Shape.FFI.API.Segmentation where++import Prelude hiding (id, error)++import Foreign+import Foreign.C++import KB.Text.Shape.FFI.Enums+import KB.Text.Shape.FFI.Flags+import KB.Text.Shape.FFI.Handles+import KB.Text.Shape.FFI.Structs++#include "kb_text_shape.h"++{- $doc+This is a quick guess that stops at the first glyph that has a strong script/direction associated to it.++It is convenient, but only works if you are sure your input text is mono-script and mono-direction.+-}++-- | @void kbts_GuessTextProperties(void *Text, int TextSizeInBytes, kbts_text_format Format, kbts_direction *Direction, kbts_script *Script);@+foreign import ccall "kbts_GuessTextProperties" kbts_GuessTextProperties+ :: Ptr () -- ^ Text+ -> CInt -- ^ TextSizeInBytes+ -> TextFormat+ -> Ptr Direction+ -> Ptr Script+ -> IO ()++-- | @void kbts_GuessTextPropertiesUtf32(const int *Utf32, int Utf32Count, kbts_direction *Direction, kbts_script *Script);@+foreign import ccall "kbts_GuessTextPropertiesUtf32" kbts_GuessTextPropertiesUtf32+ :: Ptr CInt+ -> CInt -- ^ Utf32Count+ -> Ptr Direction+ -> Ptr Script+ -> IO ()++-- | @void kbts_GuessTextPropertiesUtf8(const char *Utf8, int Utf8Length, kbts_direction *Direction, kbts_script *Script);@+foreign import ccall "kbts_GuessTextPropertiesUtf8" kbts_GuessTextPropertiesUtf8+ :: Ptr CChar+ -> CInt -- ^ Utf8Length+ -> Ptr Direction+ -> Ptr Script+ -> IO ()++-- | @void kbts_BreakBegin(kbts_break_state *State, kbts_direction ParagraphDirection, kbts_japanese_line_break_style JapaneseLineBreakStyle, kbts_break_config_flags ConfigFlags);@+foreign import ccall "kbts_BreakBegin" kbts_BreakBegin+ :: BreakState+ -> Direction -- ^ ParagraphDirection+ -> JapaneseLineBreakStyle+ -> BreakConfigFlags+ -> IO ()++-- | @void kbts_BreakAddCodepoint(kbts_break_state *State, int Codepoint, int PositionIncrement, int EndOfText);@+foreign import ccall "kbts_BreakAddCodepoint" kbts_BreakAddCodepoint+ :: BreakState+ -> CInt -- ^ Codepoint+ -> CInt -- ^ PositionIncrement+ -> CInt -- ^ EndOfText+ -> IO ()++-- | @void kbts_BreakEnd(kbts_break_state *State);@+foreign import ccall "kbts_BreakEnd" kbts_BreakEnd+ :: BreakState+ -> IO ()++-- | @int kbts_Break(kbts_break_state *State, kbts_break *Break);@+foreign import ccall "kbts_Break" kbts_Break+ :: BreakState+ -> Ptr Break+ -> IO CInt++-- | @void kbts_BreakEntireString(kbts_direction Direction, kbts_japanese_line_break_style JapaneseLineBreakStyle, kbts_break_config_flags ConfigFlags, const void *Input, int InputSizeInBytes, kbts_text_format InputFormat, kbts_break *Breaks, int BreakCapacity, int *BreakCount, kbts_break_flags *BreakFlags, int BreakFlagCapacity, int *BreakFlagCount);@+foreign import ccall "kbts_BreakEntireString" kbts_BreakEntireString+ :: Direction+ -> JapaneseLineBreakStyle+ -> BreakConfigFlags+ -> Ptr () -- ^ Input+ -> CInt -- ^ InputSizeInBytes+ -> TextFormat+ -> Ptr Break+ -> CInt -- ^ BreakCapacity+ -> Ptr CInt -- ^ BreakCount+ -> Ptr BreakFlags+ -> CInt -- ^ BreakFlagCapacity+ -> Ptr CInt -- ^ BreakFlagCount+ -> IO ()++-- | @void kbts_BreakEntireStringUtf32(kbts_direction Direction, kbts_japanese_line_break_style JapaneseLineBreakStyle, kbts_break_config_flags ConfigFlags, const int *Utf32, int Utf32Count, kbts_break *Breaks, int BreakCapacity, int *BreakCount, kbts_break_flags *BreakFlags, int BreakFlagCapacity, int *BreakFlagCount);@+foreign import ccall "kbts_BreakEntireStringUtf32" kbts_BreakEntireStringUtf32+ :: Direction+ -> JapaneseLineBreakStyle+ -> BreakConfigFlags+ -> Ptr () -- ^ Input+ -> CInt -- ^ Utf32Count+ -> Ptr Break+ -> CInt -- ^ BreakCapacity+ -> Ptr CInt -- ^ BreakCount+ -> Ptr BreakFlags+ -> CInt -- ^ BreakFlagCapacity+ -> Ptr CInt -- ^ BreakFlagCount+ -> IO ()++-- | @void kbts_BreakEntireStringUtf8(kbts_direction Direction, kbts_japanese_line_break_style JapaneseLineBreakStyle, kbts_break_config_flags ConfigFlags, const char *Utf8, int Utf8Length, kbts_break *Breaks, int BreakCapacity, int *BreakCount, kbts_break_flags *BreakFlags, int BreakFlagCapacity, int *BreakFlagCount);@+foreign import ccall "kbts_BreakEntireStringUtf8" kbts_BreakEntireStringUtf8+ :: Direction+ -> JapaneseLineBreakStyle+ -> BreakConfigFlags+ -> Ptr () -- ^ Input+ -> CInt -- ^ Utf8Length+ -> IO ()
+ src/KB/Text/Shape/FFI/Allocator.hsc view
@@ -0,0 +1,99 @@+module KB.Text.Shape.FFI.Allocator where++import Control.Exception++import Foreign+import Foreign.C++#include "kb_text_shape.h"++{- $doc+@+ typedef void kbts_allocator_function(void *Data, kbts_allocator_op *Op);+ [Data] the custom data pointer you passed in along with your allocator.+ [Op] the memory request. It is of this type:++ :kbts_allocator_op+ :allocator_op+ typedef struct kbts_allocator_op+ {+ kbts_allocator_op_kind Kind;++ union+ {+ kbts_allocator_op_allocate Allocate;+ kbts_allocator_op_free Free;+ };+ } kbts_allocator_op;+@++And the possible op kinds are:+ KBTS_ALLOCATOR_OP_KIND_ALLOCATE+ KBTS_ALLOCATOR_OP_KIND_FREE++ALLOCATE expects you to fill in Op->Allocate.Pointer.+ The allocation does not need to be aligned.+FREE expects you to free Op->Free.Pointer.+-}++-- | @void kbts_allocator_function(void *Data, kbts_allocator_op *Op);@+type Allocator = Ptr () -> Ptr Op -> IO ()++foreign import ccall "wrapper"+ mkAllocator :: Allocator -> IO (FunPtr Allocator)++freeAllocator :: FunPtr Allocator -> IO ()+freeAllocator = freeHaskellFunPtr++withAllocator :: Allocator -> (FunPtr Allocator -> IO a) -> IO a+withAllocator fun = bracket (mkAllocator fun) freeAllocator++newtype OpKind = OpKind CInt+ deriving (Eq, Ord, Show)+ deriving newtype (Storable)++pattern OP_KIND_NONE :: OpKind+pattern OP_KIND_NONE = OpKind (#const KBTS_ALLOCATOR_OP_KIND_NONE)++pattern OP_KIND_ALLOCATE :: OpKind+pattern OP_KIND_ALLOCATE = OpKind (#const KBTS_ALLOCATOR_OP_KIND_ALLOCATE)++pattern OP_KIND_FREE :: OpKind+pattern OP_KIND_FREE = OpKind (#const KBTS_ALLOCATOR_OP_KIND_FREE)++data Op = Op+ { kind :: OpKind+ , pointer :: Ptr ()+ , size :: Word32 -- ^ only for 'ALLOCATOR_OP_KIND_ALLOCATE'+ } deriving (Eq, Show)++opUnionBase :: Int+opUnionBase = max (sizeOf (undefined :: OpKind)) (alignment (undefined :: Ptr ()))++instance Storable Op where+ alignment ~_ = #alignment kbts_allocator_op+ sizeOf ~_ = #size kbts_allocator_op++ peek ptr = do+ kind <- (#peek kbts_allocator_op, Kind) ptr+ case kind of+ OP_KIND_ALLOCATE -> do+ pointer <- peekByteOff ptr $ opUnionBase + (#offset kbts_allocator_op_allocate, Pointer)+ size <- peekByteOff ptr $ opUnionBase + (#offset kbts_allocator_op_allocate, Size)+ pure $ Op kind pointer size+ OP_KIND_FREE -> do+ pointer <- peekByteOff ptr $ opUnionBase + (#offset kbts_allocator_op_allocate, Pointer)+ pure $ Op kind pointer 0+ _none_etc -> do+ pure $ Op kind nullPtr 0++ poke ptr Op{..} = do+ (#poke kbts_allocator_op, Kind) ptr kind+ case kind of+ OP_KIND_ALLOCATE -> do+ pokeByteOff ptr (opUnionBase + (#offset kbts_allocator_op_allocate, Pointer)) pointer+ pokeByteOff ptr (opUnionBase + (#offset kbts_allocator_op_allocate, Size)) size+ OP_KIND_FREE ->+ pokeByteOff ptr (opUnionBase + (#offset kbts_allocator_op_allocate, Pointer)) pointer+ _ ->+ pure ()
+ src/KB/Text/Shape/FFI/Enums.hsc view
@@ -0,0 +1,434 @@+module KB.Text.Shape.FFI.Enums+ ( module KB.Text.Shape.FFI.Enums+ , module RE+ ) where++import Foreign++import KB.Text.Shape.FFI.Enums.FeatureTag as RE+import KB.Text.Shape.FFI.Enums.Language as RE+import KB.Text.Shape.FFI.Enums.Script as RE++#include "kb_text_shape.h"++-- ** Version++newtype Version = Version Word32+ deriving (Eq, Ord)+ deriving newtype (Storable)++instance Show Version where+ showsPrec d = \case+ VERSION_1_X -> showString "VERSION_1_X"+ VERSION_2_0 -> showString "VERSION_2_0"+ Version huh -> showParen (d > 10) $ showString "Version " . showsPrec 11 huh++pattern VERSION_1_X :: Version+pattern VERSION_1_X = Version (#const KBTS_VERSION_1_X)++pattern VERSION_2_0 :: Version+pattern VERSION_2_0 = Version (#const KBTS_VERSION_2_0)++pattern VERSION_CURRENT :: Version+pattern VERSION_CURRENT = Version (#const KBTS_VERSION_CURRENT)++-- ** BlobVersion++newtype BlobVersion = BlobVersion Word32+ deriving (Eq, Ord)+ deriving newtype (Storable)++instance Show BlobVersion where+ showsPrec d = \case+ BLOB_VERSION_INVALID -> showString "BLOB_VERSION_INVALID"+ BLOB_VERSION_INITIAL -> showString "BLOB_VERSION_INITIAL"+ BlobVersion huh -> showParen (d > 10) $ showString "BlobVersion " . showsPrec 11 huh++pattern BLOB_VERSION_INVALID :: BlobVersion+pattern BLOB_VERSION_INVALID = BlobVersion (#const KBTS_BLOB_VERSION_INVALID)++pattern BLOB_VERSION_INITIAL :: BlobVersion+pattern BLOB_VERSION_INITIAL = BlobVersion (#const KBTS_BLOB_VERSION_INITIAL)++pattern BLOB_VERSION_CURRENT :: BlobVersion+pattern BLOB_VERSION_CURRENT = BlobVersion (#const KBTS_BLOB_VERSION_CURRENT)++-- ** Direction++newtype Direction = Direction Word32+ deriving (Eq, Ord)+ deriving newtype (Storable)++instance Show Direction where+ showsPrec d = \case+ DIRECTION_DONT_KNOW -> showString "DIRECTION_DONT_KNOW"+ DIRECTION_LTR -> showString "DIRECTION_LTR"+ DIRECTION_RTL -> showString "DIRECTION_RTL"+ Direction huh -> showParen (d > 10) $ showString "Direction " . showsPrec 11 huh++pattern DIRECTION_DONT_KNOW :: Direction+pattern DIRECTION_DONT_KNOW = Direction (#const KBTS_DIRECTION_DONT_KNOW)++pattern DIRECTION_LTR :: Direction+pattern DIRECTION_LTR = Direction (#const KBTS_DIRECTION_LTR)++pattern DIRECTION_RTL :: Direction+pattern DIRECTION_RTL = Direction (#const KBTS_DIRECTION_RTL)++newtype ShapeError = ShapeError Word32+ deriving (Eq, Ord)+ deriving newtype (Storable)++instance Show ShapeError where+ showsPrec d = \case+ SHAPE_ERROR_NONE -> showString "SHAPE_ERROR_NONE"+ SHAPE_ERROR_INVALID_FONT -> showString "SHAPE_ERROR_INVALID_FONT"+ SHAPE_ERROR_GAVE_TEXT_BEFORE_CALLING_BEGIN -> showString "SHAPE_ERROR_GAVE_TEXT_BEFORE_CALLING_BEGIN"+ SHAPE_ERROR_OUT_OF_MEMORY -> showString "SHAPE_ERROR_OUT_OF_MEMORY"+ ShapeError huh -> showParen (d > 10) $ showString "ShapeError " . showsPrec 11 huh++pattern SHAPE_ERROR_NONE :: ShapeError+pattern SHAPE_ERROR_NONE = ShapeError (#const KBTS_SHAPE_ERROR_NONE)++pattern SHAPE_ERROR_INVALID_FONT :: ShapeError+pattern SHAPE_ERROR_INVALID_FONT = ShapeError (#const KBTS_SHAPE_ERROR_INVALID_FONT)++pattern SHAPE_ERROR_GAVE_TEXT_BEFORE_CALLING_BEGIN :: ShapeError+pattern SHAPE_ERROR_GAVE_TEXT_BEFORE_CALLING_BEGIN = ShapeError (#const KBTS_SHAPE_ERROR_GAVE_TEXT_BEFORE_CALLING_BEGIN)++pattern SHAPE_ERROR_OUT_OF_MEMORY :: ShapeError+pattern SHAPE_ERROR_OUT_OF_MEMORY = ShapeError (#const KBTS_SHAPE_ERROR_OUT_OF_MEMORY)++newtype UserIdGenerationMode = UserIdGenerationMode Word32+ deriving (Eq, Ord)+ deriving newtype (Storable)++instance Show UserIdGenerationMode where+ showsPrec d = \case+ USER_ID_GENERATION_MODE_CODEPOINT_INDEX -> showString "USER_ID_GENERATION_MODE_CODEPOINT_INDEX"+ USER_ID_GENERATION_MODE_SOURCE_INDEX -> showString "USER_ID_GENERATION_MODE_SOURCE_INDEX"+ UserIdGenerationMode huh -> showParen (d > 10) $ showString "UserIdGenerationMode " . showsPrec 11 huh++pattern USER_ID_GENERATION_MODE_CODEPOINT_INDEX :: UserIdGenerationMode+pattern USER_ID_GENERATION_MODE_CODEPOINT_INDEX = UserIdGenerationMode (#const KBTS_USER_ID_GENERATION_MODE_CODEPOINT_INDEX)++pattern USER_ID_GENERATION_MODE_SOURCE_INDEX :: UserIdGenerationMode+pattern USER_ID_GENERATION_MODE_SOURCE_INDEX = UserIdGenerationMode (#const KBTS_USER_ID_GENERATION_MODE_SOURCE_INDEX)++newtype LoadFontError = LoadFontError Word32+ deriving (Eq, Ord)+ deriving newtype (Storable)++instance Show LoadFontError where+ showsPrec d = \case+ LOAD_FONT_ERROR_NONE -> showString "LOAD_FONT_ERROR_NONE"+ LOAD_FONT_ERROR_NEED_TO_CREATE_BLOB -> showString "LOAD_FONT_ERROR_NEED_TO_CREATE_BLOB"+ LOAD_FONT_ERROR_INVALID_FONT -> showString "LOAD_FONT_ERROR_INVALID_FONT"+ LOAD_FONT_ERROR_OUT_OF_MEMORY -> showString "LOAD_FONT_ERROR_OUT_OF_MEMORY"+ LOAD_FONT_ERROR_COULD_NOT_OPEN_FILE -> showString "LOAD_FONT_ERROR_COULD_NOT_OPEN_FILE"+ LOAD_FONT_ERROR_READ_ERROR -> showString "LOAD_FONT_ERROR_READ_ERROR"+ LoadFontError huh -> showParen (d > 10) $ showString "LoadFontError " . showsPrec 11 huh++pattern LOAD_FONT_ERROR_NONE :: LoadFontError+pattern LOAD_FONT_ERROR_NONE = LoadFontError #const KBTS_LOAD_FONT_ERROR_NONE++pattern LOAD_FONT_ERROR_NEED_TO_CREATE_BLOB :: LoadFontError+pattern LOAD_FONT_ERROR_NEED_TO_CREATE_BLOB = LoadFontError #const KBTS_LOAD_FONT_ERROR_NEED_TO_CREATE_BLOB++pattern LOAD_FONT_ERROR_INVALID_FONT :: LoadFontError+pattern LOAD_FONT_ERROR_INVALID_FONT = LoadFontError #const KBTS_LOAD_FONT_ERROR_INVALID_FONT++pattern LOAD_FONT_ERROR_OUT_OF_MEMORY :: LoadFontError+pattern LOAD_FONT_ERROR_OUT_OF_MEMORY = LoadFontError #const KBTS_LOAD_FONT_ERROR_OUT_OF_MEMORY++pattern LOAD_FONT_ERROR_COULD_NOT_OPEN_FILE :: LoadFontError+pattern LOAD_FONT_ERROR_COULD_NOT_OPEN_FILE = LoadFontError #const KBTS_LOAD_FONT_ERROR_COULD_NOT_OPEN_FILE++pattern LOAD_FONT_ERROR_READ_ERROR :: LoadFontError+pattern LOAD_FONT_ERROR_READ_ERROR = LoadFontError #const KBTS_LOAD_FONT_ERROR_READ_ERROR++newtype FontWeight = FontWeight Word32+ deriving (Eq, Ord)+ deriving newtype (Storable)++instance Show FontWeight where+ showsPrec d = \case+ FONT_WEIGHT_UNKNOWN -> showString "FONT_WEIGHT_UNKNOWN"+ FONT_WEIGHT_THIN -> showString "FONT_WEIGHT_THIN"+ FONT_WEIGHT_EXTRA_LIGHT -> showString "FONT_WEIGHT_EXTRA_LIGHT"+ FONT_WEIGHT_LIGHT -> showString "FONT_WEIGHT_LIGHT"+ FONT_WEIGHT_NORMAL -> showString "FONT_WEIGHT_NORMAL"+ FONT_WEIGHT_MEDIUM -> showString "FONT_WEIGHT_MEDIUM"+ FONT_WEIGHT_SEMI_BOLD -> showString "FONT_WEIGHT_SEMI_BOLD"+ FONT_WEIGHT_BOLD -> showString "FONT_WEIGHT_BOLD"+ FONT_WEIGHT_EXTRA_BOLD -> showString "FONT_WEIGHT_EXTRA_BOLD"+ FONT_WEIGHT_BLACK -> showString "FONT_WEIGHT_BLACK"+ FontWeight huh -> showParen (d > 10) $ showString "FontWeight " . showsPrec 11 huh++pattern FONT_WEIGHT_UNKNOWN :: FontWeight+pattern FONT_WEIGHT_UNKNOWN = FontWeight (#const KBTS_FONT_WEIGHT_UNKNOWN)++pattern FONT_WEIGHT_THIN :: FontWeight+pattern FONT_WEIGHT_THIN = FontWeight (#const KBTS_FONT_WEIGHT_THIN)++pattern FONT_WEIGHT_EXTRA_LIGHT :: FontWeight+pattern FONT_WEIGHT_EXTRA_LIGHT = FontWeight (#const KBTS_FONT_WEIGHT_EXTRA_LIGHT)++pattern FONT_WEIGHT_LIGHT :: FontWeight+pattern FONT_WEIGHT_LIGHT = FontWeight (#const KBTS_FONT_WEIGHT_LIGHT)++pattern FONT_WEIGHT_NORMAL :: FontWeight+pattern FONT_WEIGHT_NORMAL = FontWeight (#const KBTS_FONT_WEIGHT_NORMAL)++pattern FONT_WEIGHT_MEDIUM :: FontWeight+pattern FONT_WEIGHT_MEDIUM = FontWeight (#const KBTS_FONT_WEIGHT_MEDIUM)++pattern FONT_WEIGHT_SEMI_BOLD :: FontWeight+pattern FONT_WEIGHT_SEMI_BOLD = FontWeight (#const KBTS_FONT_WEIGHT_SEMI_BOLD)++pattern FONT_WEIGHT_BOLD :: FontWeight+pattern FONT_WEIGHT_BOLD = FontWeight (#const KBTS_FONT_WEIGHT_BOLD)++pattern FONT_WEIGHT_EXTRA_BOLD :: FontWeight+pattern FONT_WEIGHT_EXTRA_BOLD = FontWeight (#const KBTS_FONT_WEIGHT_EXTRA_BOLD)++pattern FONT_WEIGHT_BLACK :: FontWeight+pattern FONT_WEIGHT_BLACK = FontWeight (#const KBTS_FONT_WEIGHT_BLACK)++newtype FontWidth = FontWidth Word32+ deriving (Eq)+ deriving newtype (Storable)++instance Show FontWidth where+ showsPrec d = \case+ FONT_WIDTH_UNKNOWN -> showString "FONT_WIDTH_UNKNOWN"+ FONT_WIDTH_ULTRA_CONDENSED -> showString "FONT_WIDTH_ULTRA_CONDENSED"+ FONT_WIDTH_EXTRA_CONDENSED -> showString "FONT_WIDTH_EXTRA_CONDENSED"+ FONT_WIDTH_CONDENSED -> showString "FONT_WIDTH_CONDENSED"+ FONT_WIDTH_SEMI_CONDENSED -> showString "FONT_WIDTH_SEMI_CONDENSED"+ FONT_WIDTH_NORMAL -> showString "FONT_WIDTH_NORMAL"+ FONT_WIDTH_SEMI_EXPANDED -> showString "FONT_WIDTH_SEMI_EXPANDED"+ FONT_WIDTH_EXPANDED -> showString "FONT_WIDTH_EXPANDED"+ FONT_WIDTH_EXTRA_EXPANDED -> showString "FONT_WIDTH_EXTRA_EXPANDED"+ FONT_WIDTH_ULTRA_EXPANDED -> showString "FONT_WIDTH_ULTRA_EXPANDED"+ FontWidth huh -> showParen (d > 10) $ showString "FontWidth " . showsPrec 11 huh++pattern FONT_WIDTH_UNKNOWN :: FontWidth+pattern FONT_WIDTH_UNKNOWN = FontWidth (#const KBTS_FONT_WIDTH_UNKNOWN)++pattern FONT_WIDTH_ULTRA_CONDENSED :: FontWidth+pattern FONT_WIDTH_ULTRA_CONDENSED = FontWidth (#const KBTS_FONT_WIDTH_ULTRA_CONDENSED)++pattern FONT_WIDTH_EXTRA_CONDENSED :: FontWidth+pattern FONT_WIDTH_EXTRA_CONDENSED = FontWidth (#const KBTS_FONT_WIDTH_EXTRA_CONDENSED)++pattern FONT_WIDTH_CONDENSED :: FontWidth+pattern FONT_WIDTH_CONDENSED = FontWidth (#const KBTS_FONT_WIDTH_CONDENSED)++pattern FONT_WIDTH_SEMI_CONDENSED :: FontWidth+pattern FONT_WIDTH_SEMI_CONDENSED = FontWidth (#const KBTS_FONT_WIDTH_SEMI_CONDENSED)++pattern FONT_WIDTH_NORMAL :: FontWidth+pattern FONT_WIDTH_NORMAL = FontWidth (#const KBTS_FONT_WIDTH_NORMAL)++pattern FONT_WIDTH_SEMI_EXPANDED :: FontWidth+pattern FONT_WIDTH_SEMI_EXPANDED = FontWidth (#const KBTS_FONT_WIDTH_SEMI_EXPANDED)++pattern FONT_WIDTH_EXPANDED :: FontWidth+pattern FONT_WIDTH_EXPANDED = FontWidth (#const KBTS_FONT_WIDTH_EXPANDED)++pattern FONT_WIDTH_EXTRA_EXPANDED :: FontWidth+pattern FONT_WIDTH_EXTRA_EXPANDED = FontWidth (#const KBTS_FONT_WIDTH_EXTRA_EXPANDED)++pattern FONT_WIDTH_ULTRA_EXPANDED :: FontWidth+pattern FONT_WIDTH_ULTRA_EXPANDED = FontWidth (#const KBTS_FONT_WIDTH_ULTRA_EXPANDED)++newtype FontInfoStringId = FontInfoStringId Int+ deriving (Eq, Ord)++instance Show FontInfoStringId where+ showsPrec d = \case+ FONT_INFO_STRING_ID_NONE -> showString "FONT_INFO_STRING_ID_NONE"+ FONT_INFO_STRING_ID_COPYRIGHT -> showString "FONT_INFO_STRING_ID_COPYRIGHT"+ FONT_INFO_STRING_ID_FAMILY -> showString "FONT_INFO_STRING_ID_FAMILY"+ FONT_INFO_STRING_ID_SUBFAMILY -> showString "FONT_INFO_STRING_ID_SUBFAMILY"+ FONT_INFO_STRING_ID_UID -> showString "FONT_INFO_STRING_ID_UID"+ FONT_INFO_STRING_ID_FULL_NAME -> showString "FONT_INFO_STRING_ID_FULL_NAME"+ FONT_INFO_STRING_ID_VERSION -> showString "FONT_INFO_STRING_ID_VERSION"+ FONT_INFO_STRING_ID_POSTSCRIPT_NAME -> showString "FONT_INFO_STRING_ID_POSTSCRIPT_NAME"+ FONT_INFO_STRING_ID_TRADEMARK -> showString "FONT_INFO_STRING_ID_TRADEMARK"+ FONT_INFO_STRING_ID_MANUFACTURER -> showString "FONT_INFO_STRING_ID_MANUFACTURER"+ FONT_INFO_STRING_ID_DESIGNER -> showString "FONT_INFO_STRING_ID_DESIGNER"+ FONT_INFO_STRING_ID_TYPOGRAPHIC_FAMILY -> showString "FONT_INFO_STRING_ID_TYPOGRAPHIC_FAMILY"+ FONT_INFO_STRING_ID_TYPOGRAPHIC_SUBFAMILY -> showString "FONT_INFO_STRING_ID_TYPOGRAPHIC_SUBFAMILY"+ FontInfoStringId huh -> showParen (d > 10) $ showString "FontInfoStringId " . showsPrec 11 huh++pattern FONT_INFO_STRING_ID_NONE :: FontInfoStringId+pattern FONT_INFO_STRING_ID_NONE = FontInfoStringId (#const KBTS_FONT_INFO_STRING_ID_NONE)++pattern FONT_INFO_STRING_ID_COPYRIGHT :: FontInfoStringId+pattern FONT_INFO_STRING_ID_COPYRIGHT = FontInfoStringId (#const KBTS_FONT_INFO_STRING_ID_COPYRIGHT)++pattern FONT_INFO_STRING_ID_FAMILY :: FontInfoStringId+pattern FONT_INFO_STRING_ID_FAMILY = FontInfoStringId (#const KBTS_FONT_INFO_STRING_ID_FAMILY)++pattern FONT_INFO_STRING_ID_SUBFAMILY :: FontInfoStringId+pattern FONT_INFO_STRING_ID_SUBFAMILY = FontInfoStringId (#const KBTS_FONT_INFO_STRING_ID_SUBFAMILY)++pattern FONT_INFO_STRING_ID_UID :: FontInfoStringId+pattern FONT_INFO_STRING_ID_UID = FontInfoStringId (#const KBTS_FONT_INFO_STRING_ID_UID)++pattern FONT_INFO_STRING_ID_FULL_NAME :: FontInfoStringId+pattern FONT_INFO_STRING_ID_FULL_NAME = FontInfoStringId (#const KBTS_FONT_INFO_STRING_ID_FULL_NAME)++pattern FONT_INFO_STRING_ID_VERSION :: FontInfoStringId+pattern FONT_INFO_STRING_ID_VERSION = FontInfoStringId (#const KBTS_FONT_INFO_STRING_ID_VERSION)++pattern FONT_INFO_STRING_ID_POSTSCRIPT_NAME :: FontInfoStringId+pattern FONT_INFO_STRING_ID_POSTSCRIPT_NAME = FontInfoStringId (#const KBTS_FONT_INFO_STRING_ID_POSTSCRIPT_NAME)++pattern FONT_INFO_STRING_ID_TRADEMARK :: FontInfoStringId+pattern FONT_INFO_STRING_ID_TRADEMARK = FontInfoStringId (#const KBTS_FONT_INFO_STRING_ID_TRADEMARK)++pattern FONT_INFO_STRING_ID_MANUFACTURER :: FontInfoStringId+pattern FONT_INFO_STRING_ID_MANUFACTURER = FontInfoStringId (#const KBTS_FONT_INFO_STRING_ID_MANUFACTURER)++pattern FONT_INFO_STRING_ID_DESIGNER :: FontInfoStringId+pattern FONT_INFO_STRING_ID_DESIGNER = FontInfoStringId (#const KBTS_FONT_INFO_STRING_ID_DESIGNER)++pattern FONT_INFO_STRING_ID_TYPOGRAPHIC_FAMILY :: FontInfoStringId+pattern FONT_INFO_STRING_ID_TYPOGRAPHIC_FAMILY = FontInfoStringId (#const KBTS_FONT_INFO_STRING_ID_TYPOGRAPHIC_FAMILY)++pattern FONT_INFO_STRING_ID_TYPOGRAPHIC_SUBFAMILY :: FontInfoStringId+pattern FONT_INFO_STRING_ID_TYPOGRAPHIC_SUBFAMILY = FontInfoStringId (#const KBTS_FONT_INFO_STRING_ID_TYPOGRAPHIC_SUBFAMILY)++pattern FONT_INFO_STRING_ID_COUNT :: Int+pattern FONT_INFO_STRING_ID_COUNT = #const KBTS_FONT_INFO_STRING_ID_COUNT++newtype TextFormat = TextFormat Word32+ deriving (Eq, Ord)+ deriving newtype (Storable)++instance Show TextFormat where+ showsPrec d = \case+ TEXT_FORMAT_NONE -> showString "TEXT_FORMAT_NONE"+ TEXT_FORMAT_UTF32 -> showString "TEXT_FORMAT_UTF32"+ TEXT_FORMAT_UTF8 -> showString "TEXT_FORMAT_UTF8"+ TextFormat huh -> showParen (d > 10) $ showString "TextFormat " . showsPrec 11 huh++pattern TEXT_FORMAT_NONE :: TextFormat+pattern TEXT_FORMAT_NONE = TextFormat (#const KBTS_TEXT_FORMAT_NONE)++pattern TEXT_FORMAT_UTF32 :: TextFormat+pattern TEXT_FORMAT_UTF32 = TextFormat (#const KBTS_TEXT_FORMAT_UTF32)++pattern TEXT_FORMAT_UTF8 :: TextFormat+pattern TEXT_FORMAT_UTF8 = TextFormat (#const KBTS_TEXT_FORMAT_UTF8)++{- |+ Japanese text contains "kinsoku" characters, around which breaking a line is forbidden.+ Exactly which characters are "kinsoku" or not depends on the context:+ - Strict style has the largest amount of kinsoku characters, which leads to longer lines.+ - Loose style has the smallest amount of kinsoku characters, which leads to smaller lines.+ - Normal style is somewhere in the middle.+ Note that, while the Unicode standard mentions all three of these styles, it does not mention+ any differences between the normal and loose styles.+ As such, normal and loose styles currently behave the same.+-}+newtype JapaneseLineBreakStyle = JapaneseLineBreakStyle Word8+ deriving (Eq, Ord)+ deriving (Storable)++instance Show JapaneseLineBreakStyle where+ showsPrec d = \case+ JAPANESE_LINE_BREAK_STYLE_STRICT -> showString "JAPANESE_LINE_BREAK_STYLE_STRICT"+ JAPANESE_LINE_BREAK_STYLE_NORMAL -> showString "JAPANESE_LINE_BREAK_STYLE_NORMAL"+ JAPANESE_LINE_BREAK_STYLE_LOOSE -> showString "JAPANESE_LINE_BREAK_STYLE_LOOSE"+ JapaneseLineBreakStyle huh -> showParen (d > 10) $ showString "JapaneseLineBreakStyle " . showsPrec 11 huh++{- |+ The Unicode standard does not define what strict style is used for.+ Supposedly, it is used for anything that does not fall into the other two categories of text.+-}+pattern JAPANESE_LINE_BREAK_STYLE_STRICT :: JapaneseLineBreakStyle+pattern JAPANESE_LINE_BREAK_STYLE_STRICT = JapaneseLineBreakStyle (#const KBTS_JAPANESE_LINE_BREAK_STYLE_STRICT)++-- | Normal style is used for books and documents.+pattern JAPANESE_LINE_BREAK_STYLE_NORMAL :: JapaneseLineBreakStyle+pattern JAPANESE_LINE_BREAK_STYLE_NORMAL = JapaneseLineBreakStyle (#const KBTS_JAPANESE_LINE_BREAK_STYLE_NORMAL)++-- | Loose style is used for newspapers, and (I assume) any other narrow column format.+pattern JAPANESE_LINE_BREAK_STYLE_LOOSE :: JapaneseLineBreakStyle+pattern JAPANESE_LINE_BREAK_STYLE_LOOSE = JapaneseLineBreakStyle (#const KBTS_JAPANESE_LINE_BREAK_STYLE_LOOSE)++-- ** UnicodeJoiningFeature++newtype UnicodeJoiningFeature = UnicodeJoiningFeature Word8+ deriving (Eq, Ord)+ deriving (Storable)++instance Show UnicodeJoiningFeature where+ showsPrec d = \case+ JOINING_FEATURE_ISOL -> showString "JOINING_FEATURE_ISOL"+ JOINING_FEATURE_FINA -> showString "JOINING_FEATURE_FINA"+ JOINING_FEATURE_FIN2 -> showString "JOINING_FEATURE_FIN2"+ JOINING_FEATURE_FIN3 -> showString "JOINING_FEATURE_FIN3"+ JOINING_FEATURE_MEDI -> showString "JOINING_FEATURE_MEDI"+ JOINING_FEATURE_MED2 -> showString "JOINING_FEATURE_MED2"+ JOINING_FEATURE_INIT -> showString "JOINING_FEATURE_INIT"+ UnicodeJoiningFeature huh -> showParen (d > 10) $ showString "UnicodeJoiningFeature " . showsPrec 11 huh++pattern JOINING_FEATURE_ISOL :: UnicodeJoiningFeature+pattern JOINING_FEATURE_ISOL = UnicodeJoiningFeature (#const KBTS_JOINING_FEATURE_ISOL)++pattern JOINING_FEATURE_FINA :: UnicodeJoiningFeature+pattern JOINING_FEATURE_FINA = UnicodeJoiningFeature (#const KBTS_JOINING_FEATURE_FINA)++pattern JOINING_FEATURE_FIN2 :: UnicodeJoiningFeature+pattern JOINING_FEATURE_FIN2 = UnicodeJoiningFeature (#const KBTS_JOINING_FEATURE_FIN2)++pattern JOINING_FEATURE_FIN3 :: UnicodeJoiningFeature+pattern JOINING_FEATURE_FIN3 = UnicodeJoiningFeature (#const KBTS_JOINING_FEATURE_FIN3)++pattern JOINING_FEATURE_MEDI :: UnicodeJoiningFeature+pattern JOINING_FEATURE_MEDI = UnicodeJoiningFeature (#const KBTS_JOINING_FEATURE_MEDI)++pattern JOINING_FEATURE_MED2 :: UnicodeJoiningFeature+pattern JOINING_FEATURE_MED2 = UnicodeJoiningFeature (#const KBTS_JOINING_FEATURE_MED2)++pattern JOINING_FEATURE_INIT :: UnicodeJoiningFeature+pattern JOINING_FEATURE_INIT = UnicodeJoiningFeature (#const KBTS_JOINING_FEATURE_INIT)++-- ** UnicodeJoiningType++newtype UnicodeJoiningType = UnicodeJoiningType Word8+ deriving (Eq, Ord)+ deriving (Storable)++instance Show UnicodeJoiningType where+ showsPrec d = \case+ UNICODE_JOINING_TYPE_NONE -> showString "UNICODE_JOINING_TYPE_NONE"+ UNICODE_JOINING_TYPE_LEFT -> showString "UNICODE_JOINING_TYPE_LEFT"+ UNICODE_JOINING_TYPE_DUAL -> showString "UNICODE_JOINING_TYPE_DUAL"+ UNICODE_JOINING_TYPE_FORCE -> showString "UNICODE_JOINING_TYPE_FORCE"+ UNICODE_JOINING_TYPE_RIGHT -> showString "UNICODE_JOINING_TYPE_RIGHT"+ UNICODE_JOINING_TYPE_TRANSPARENT -> showString "UNICODE_JOINING_TYPE_TRANSPARENT"+ UnicodeJoiningType huh -> showParen (d > 10) $ showString "UnicodeJoiningType " . showsPrec 11 huh++pattern UNICODE_JOINING_TYPE_NONE :: UnicodeJoiningType+pattern UNICODE_JOINING_TYPE_NONE = UnicodeJoiningType (#const KBTS_UNICODE_JOINING_TYPE_NONE)++pattern UNICODE_JOINING_TYPE_LEFT :: UnicodeJoiningType+pattern UNICODE_JOINING_TYPE_LEFT = UnicodeJoiningType (#const KBTS_UNICODE_JOINING_TYPE_LEFT)++pattern UNICODE_JOINING_TYPE_DUAL :: UnicodeJoiningType+pattern UNICODE_JOINING_TYPE_DUAL = UnicodeJoiningType (#const KBTS_UNICODE_JOINING_TYPE_DUAL)++pattern UNICODE_JOINING_TYPE_FORCE :: UnicodeJoiningType+pattern UNICODE_JOINING_TYPE_FORCE = UnicodeJoiningType (#const KBTS_UNICODE_JOINING_TYPE_FORCE)++pattern UNICODE_JOINING_TYPE_RIGHT :: UnicodeJoiningType+pattern UNICODE_JOINING_TYPE_RIGHT = UnicodeJoiningType (#const KBTS_UNICODE_JOINING_TYPE_RIGHT)++pattern UNICODE_JOINING_TYPE_TRANSPARENT :: UnicodeJoiningType+pattern UNICODE_JOINING_TYPE_TRANSPARENT = UnicodeJoiningType (#const KBTS_UNICODE_JOINING_TYPE_TRANSPARENT)
+ src/KB/Text/Shape/FFI/Enums/FeatureTag.hsc view
@@ -0,0 +1,1247 @@+module KB.Text.Shape.FFI.Enums.FeatureTag where++import Prelude hiding (id, error)+import Foreign++import Data.Map (Map)+import Data.Map.Strict qualified as Map++#include "kb_text_shape.h"++newtype FeatureTag = FeatureTag Word32+ deriving (Eq, Ord)+ deriving newtype (Storable)++instance Show FeatureTag where+ showsPrec d t@(FeatureTag tv) =+ case Map.lookup t featureTagNames of+ Just name -> showString name+ Nothing -> showParen (d > 10) $ showString "FeatureTag " . showsPrec 11 tv++pattern FEATURE_TAG_UNREGISTERED :: FeatureTag+pattern FEATURE_TAG_UNREGISTERED = FeatureTag 0++-- | Isolated Forms+pattern FEATURE_TAG_isol :: FeatureTag+pattern FEATURE_TAG_isol = FeatureTag (#const KBTS_FEATURE_TAG_isol)++-- | Terminal Forms+pattern FEATURE_TAG_fina :: FeatureTag+pattern FEATURE_TAG_fina = FeatureTag (#const KBTS_FEATURE_TAG_fina)++-- | Terminal Forms #2+pattern FEATURE_TAG_fin2 :: FeatureTag+pattern FEATURE_TAG_fin2 = FeatureTag (#const KBTS_FEATURE_TAG_fin2)++-- | Terminal Forms #3+pattern FEATURE_TAG_fin3 :: FeatureTag+pattern FEATURE_TAG_fin3 = FeatureTag (#const KBTS_FEATURE_TAG_fin3)++-- | Medial Forms+pattern FEATURE_TAG_medi :: FeatureTag+pattern FEATURE_TAG_medi = FeatureTag (#const KBTS_FEATURE_TAG_medi)++-- | Medial Forms #2+pattern FEATURE_TAG_med2 :: FeatureTag+pattern FEATURE_TAG_med2 = FeatureTag (#const KBTS_FEATURE_TAG_med2)++-- | Initial Forms+pattern FEATURE_TAG_init :: FeatureTag+pattern FEATURE_TAG_init = FeatureTag (#const KBTS_FEATURE_TAG_init)++-- | Leading Jamo Forms+pattern FEATURE_TAG_ljmo :: FeatureTag+pattern FEATURE_TAG_ljmo = FeatureTag (#const KBTS_FEATURE_TAG_ljmo)++-- | Vowel Jamo Forms+pattern FEATURE_TAG_vjmo :: FeatureTag+pattern FEATURE_TAG_vjmo = FeatureTag (#const KBTS_FEATURE_TAG_vjmo)++-- | Trailing Jamo Forms+pattern FEATURE_TAG_tjmo :: FeatureTag+pattern FEATURE_TAG_tjmo = FeatureTag (#const KBTS_FEATURE_TAG_tjmo)++-- | Reph Form+pattern FEATURE_TAG_rphf :: FeatureTag+pattern FEATURE_TAG_rphf = FeatureTag (#const KBTS_FEATURE_TAG_rphf)++-- | Below-base Forms+pattern FEATURE_TAG_blwf :: FeatureTag+pattern FEATURE_TAG_blwf = FeatureTag (#const KBTS_FEATURE_TAG_blwf)++-- | Half Forms+pattern FEATURE_TAG_half :: FeatureTag+pattern FEATURE_TAG_half = FeatureTag (#const KBTS_FEATURE_TAG_half)++-- | Post-base Forms+pattern FEATURE_TAG_pstf :: FeatureTag+pattern FEATURE_TAG_pstf = FeatureTag (#const KBTS_FEATURE_TAG_pstf)++-- | Above-base Forms+pattern FEATURE_TAG_abvf :: FeatureTag+pattern FEATURE_TAG_abvf = FeatureTag (#const KBTS_FEATURE_TAG_abvf)++-- | Pre-base Forms+pattern FEATURE_TAG_pref :: FeatureTag+pattern FEATURE_TAG_pref = FeatureTag (#const KBTS_FEATURE_TAG_pref)++-- | Numerators+pattern FEATURE_TAG_numr :: FeatureTag+pattern FEATURE_TAG_numr = FeatureTag (#const KBTS_FEATURE_TAG_numr)++-- | Fractions+pattern FEATURE_TAG_frac :: FeatureTag+pattern FEATURE_TAG_frac = FeatureTag (#const KBTS_FEATURE_TAG_frac)++-- | Denominators+pattern FEATURE_TAG_dnom :: FeatureTag+pattern FEATURE_TAG_dnom = FeatureTag (#const KBTS_FEATURE_TAG_dnom)++-- | Conjunct Form After Ro+pattern FEATURE_TAG_cfar :: FeatureTag+pattern FEATURE_TAG_cfar = FeatureTag (#const KBTS_FEATURE_TAG_cfar)++-- | Access All Alternates+pattern FEATURE_TAG_aalt :: FeatureTag+pattern FEATURE_TAG_aalt = FeatureTag (#const KBTS_FEATURE_TAG_aalt)++-- | Above-base Mark Positioning+pattern FEATURE_TAG_abvm :: FeatureTag+pattern FEATURE_TAG_abvm = FeatureTag (#const KBTS_FEATURE_TAG_abvm)++-- | Above-base Substitutions+pattern FEATURE_TAG_abvs :: FeatureTag+pattern FEATURE_TAG_abvs = FeatureTag (#const KBTS_FEATURE_TAG_abvs)++-- | Alternative Fractions+pattern FEATURE_TAG_afrc :: FeatureTag+pattern FEATURE_TAG_afrc = FeatureTag (#const KBTS_FEATURE_TAG_afrc)++-- | Akhand+pattern FEATURE_TAG_akhn :: FeatureTag+pattern FEATURE_TAG_akhn = FeatureTag (#const KBTS_FEATURE_TAG_akhn)++-- | Kerning for Alternate Proportional Widths+pattern FEATURE_TAG_apkn :: FeatureTag+pattern FEATURE_TAG_apkn = FeatureTag (#const KBTS_FEATURE_TAG_apkn)++-- | Below-base Mark Positioning+pattern FEATURE_TAG_blwm :: FeatureTag+pattern FEATURE_TAG_blwm = FeatureTag (#const KBTS_FEATURE_TAG_blwm)++-- | Below-base Substitutions+pattern FEATURE_TAG_blws :: FeatureTag+pattern FEATURE_TAG_blws = FeatureTag (#const KBTS_FEATURE_TAG_blws)++-- | Contextual Alternates+pattern FEATURE_TAG_calt :: FeatureTag+pattern FEATURE_TAG_calt = FeatureTag (#const KBTS_FEATURE_TAG_calt)++-- | Case-sensitive Forms+pattern FEATURE_TAG_case :: FeatureTag+pattern FEATURE_TAG_case = FeatureTag (#const KBTS_FEATURE_TAG_case)++-- | Glyph Composition / Decomposition+pattern FEATURE_TAG_ccmp :: FeatureTag+pattern FEATURE_TAG_ccmp = FeatureTag (#const KBTS_FEATURE_TAG_ccmp)++-- | Contextual Half-width Spacing+pattern FEATURE_TAG_chws :: FeatureTag+pattern FEATURE_TAG_chws = FeatureTag (#const KBTS_FEATURE_TAG_chws)++-- | Conjunct Forms+pattern FEATURE_TAG_cjct :: FeatureTag+pattern FEATURE_TAG_cjct = FeatureTag (#const KBTS_FEATURE_TAG_cjct)++-- | Contextual Ligatures+pattern FEATURE_TAG_clig :: FeatureTag+pattern FEATURE_TAG_clig = FeatureTag (#const KBTS_FEATURE_TAG_clig)++-- | Centered CJK Punctuation+pattern FEATURE_TAG_cpct :: FeatureTag+pattern FEATURE_TAG_cpct = FeatureTag (#const KBTS_FEATURE_TAG_cpct)++-- | Capital Spacing+pattern FEATURE_TAG_cpsp :: FeatureTag+pattern FEATURE_TAG_cpsp = FeatureTag (#const KBTS_FEATURE_TAG_cpsp)++-- | Contextual Swash+pattern FEATURE_TAG_cswh :: FeatureTag+pattern FEATURE_TAG_cswh = FeatureTag (#const KBTS_FEATURE_TAG_cswh)++-- | Cursive Positioning+pattern FEATURE_TAG_curs :: FeatureTag+pattern FEATURE_TAG_curs = FeatureTag (#const KBTS_FEATURE_TAG_curs)++-- | Character Variant 1+pattern FEATURE_TAG_cv01 :: FeatureTag+pattern FEATURE_TAG_cv01 = FeatureTag (#const KBTS_FEATURE_TAG_cv01)++-- | Character Variant 2+pattern FEATURE_TAG_cv02 :: FeatureTag+pattern FEATURE_TAG_cv02 = FeatureTag (#const KBTS_FEATURE_TAG_cv02)++-- | Character Variant 3+pattern FEATURE_TAG_cv03 :: FeatureTag+pattern FEATURE_TAG_cv03 = FeatureTag (#const KBTS_FEATURE_TAG_cv03)++-- | Character Variant 4+pattern FEATURE_TAG_cv04 :: FeatureTag+pattern FEATURE_TAG_cv04 = FeatureTag (#const KBTS_FEATURE_TAG_cv04)++-- | Character Variant 5+pattern FEATURE_TAG_cv05 :: FeatureTag+pattern FEATURE_TAG_cv05 = FeatureTag (#const KBTS_FEATURE_TAG_cv05)++-- | Character Variant 6+pattern FEATURE_TAG_cv06 :: FeatureTag+pattern FEATURE_TAG_cv06 = FeatureTag (#const KBTS_FEATURE_TAG_cv06)++-- | Character Variant 7+pattern FEATURE_TAG_cv07 :: FeatureTag+pattern FEATURE_TAG_cv07 = FeatureTag (#const KBTS_FEATURE_TAG_cv07)++-- | Character Variant 8+pattern FEATURE_TAG_cv08 :: FeatureTag+pattern FEATURE_TAG_cv08 = FeatureTag (#const KBTS_FEATURE_TAG_cv08)++-- | Character Variant 9+pattern FEATURE_TAG_cv09 :: FeatureTag+pattern FEATURE_TAG_cv09 = FeatureTag (#const KBTS_FEATURE_TAG_cv09)++-- | Character Variant 10+pattern FEATURE_TAG_cv10 :: FeatureTag+pattern FEATURE_TAG_cv10 = FeatureTag (#const KBTS_FEATURE_TAG_cv10)++-- | Character Variant 11+pattern FEATURE_TAG_cv11 :: FeatureTag+pattern FEATURE_TAG_cv11 = FeatureTag (#const KBTS_FEATURE_TAG_cv11)++-- | Character Variant 12+pattern FEATURE_TAG_cv12 :: FeatureTag+pattern FEATURE_TAG_cv12 = FeatureTag (#const KBTS_FEATURE_TAG_cv12)++-- | Character Variant 13+pattern FEATURE_TAG_cv13 :: FeatureTag+pattern FEATURE_TAG_cv13 = FeatureTag (#const KBTS_FEATURE_TAG_cv13)++-- | Character Variant 14+pattern FEATURE_TAG_cv14 :: FeatureTag+pattern FEATURE_TAG_cv14 = FeatureTag (#const KBTS_FEATURE_TAG_cv14)++-- | Character Variant 15+pattern FEATURE_TAG_cv15 :: FeatureTag+pattern FEATURE_TAG_cv15 = FeatureTag (#const KBTS_FEATURE_TAG_cv15)++-- | Character Variant 16+pattern FEATURE_TAG_cv16 :: FeatureTag+pattern FEATURE_TAG_cv16 = FeatureTag (#const KBTS_FEATURE_TAG_cv16)++-- | Character Variant 17+pattern FEATURE_TAG_cv17 :: FeatureTag+pattern FEATURE_TAG_cv17 = FeatureTag (#const KBTS_FEATURE_TAG_cv17)++-- | Character Variant 18+pattern FEATURE_TAG_cv18 :: FeatureTag+pattern FEATURE_TAG_cv18 = FeatureTag (#const KBTS_FEATURE_TAG_cv18)++-- | Character Variant 19+pattern FEATURE_TAG_cv19 :: FeatureTag+pattern FEATURE_TAG_cv19 = FeatureTag (#const KBTS_FEATURE_TAG_cv19)++-- | Character Variant 20+pattern FEATURE_TAG_cv20 :: FeatureTag+pattern FEATURE_TAG_cv20 = FeatureTag (#const KBTS_FEATURE_TAG_cv20)++-- | Character Variant 21+pattern FEATURE_TAG_cv21 :: FeatureTag+pattern FEATURE_TAG_cv21 = FeatureTag (#const KBTS_FEATURE_TAG_cv21)++-- | Character Variant 22+pattern FEATURE_TAG_cv22 :: FeatureTag+pattern FEATURE_TAG_cv22 = FeatureTag (#const KBTS_FEATURE_TAG_cv22)++-- | Character Variant 23+pattern FEATURE_TAG_cv23 :: FeatureTag+pattern FEATURE_TAG_cv23 = FeatureTag (#const KBTS_FEATURE_TAG_cv23)++-- | Character Variant 24+pattern FEATURE_TAG_cv24 :: FeatureTag+pattern FEATURE_TAG_cv24 = FeatureTag (#const KBTS_FEATURE_TAG_cv24)++-- | Character Variant 25+pattern FEATURE_TAG_cv25 :: FeatureTag+pattern FEATURE_TAG_cv25 = FeatureTag (#const KBTS_FEATURE_TAG_cv25)++-- | Character Variant 26+pattern FEATURE_TAG_cv26 :: FeatureTag+pattern FEATURE_TAG_cv26 = FeatureTag (#const KBTS_FEATURE_TAG_cv26)++-- | Character Variant 27+pattern FEATURE_TAG_cv27 :: FeatureTag+pattern FEATURE_TAG_cv27 = FeatureTag (#const KBTS_FEATURE_TAG_cv27)++-- | Character Variant 28+pattern FEATURE_TAG_cv28 :: FeatureTag+pattern FEATURE_TAG_cv28 = FeatureTag (#const KBTS_FEATURE_TAG_cv28)++-- | Character Variant 29+pattern FEATURE_TAG_cv29 :: FeatureTag+pattern FEATURE_TAG_cv29 = FeatureTag (#const KBTS_FEATURE_TAG_cv29)++-- | Character Variant 30+pattern FEATURE_TAG_cv30 :: FeatureTag+pattern FEATURE_TAG_cv30 = FeatureTag (#const KBTS_FEATURE_TAG_cv30)++-- | Character Variant 31+pattern FEATURE_TAG_cv31 :: FeatureTag+pattern FEATURE_TAG_cv31 = FeatureTag (#const KBTS_FEATURE_TAG_cv31)++-- | Character Variant 32+pattern FEATURE_TAG_cv32 :: FeatureTag+pattern FEATURE_TAG_cv32 = FeatureTag (#const KBTS_FEATURE_TAG_cv32)++-- | Character Variant 33+pattern FEATURE_TAG_cv33 :: FeatureTag+pattern FEATURE_TAG_cv33 = FeatureTag (#const KBTS_FEATURE_TAG_cv33)++-- | Character Variant 34+pattern FEATURE_TAG_cv34 :: FeatureTag+pattern FEATURE_TAG_cv34 = FeatureTag (#const KBTS_FEATURE_TAG_cv34)++-- | Character Variant 35+pattern FEATURE_TAG_cv35 :: FeatureTag+pattern FEATURE_TAG_cv35 = FeatureTag (#const KBTS_FEATURE_TAG_cv35)++-- | Character Variant 36+pattern FEATURE_TAG_cv36 :: FeatureTag+pattern FEATURE_TAG_cv36 = FeatureTag (#const KBTS_FEATURE_TAG_cv36)++-- | Character Variant 37+pattern FEATURE_TAG_cv37 :: FeatureTag+pattern FEATURE_TAG_cv37 = FeatureTag (#const KBTS_FEATURE_TAG_cv37)++-- | Character Variant 38+pattern FEATURE_TAG_cv38 :: FeatureTag+pattern FEATURE_TAG_cv38 = FeatureTag (#const KBTS_FEATURE_TAG_cv38)++-- | Character Variant 39+pattern FEATURE_TAG_cv39 :: FeatureTag+pattern FEATURE_TAG_cv39 = FeatureTag (#const KBTS_FEATURE_TAG_cv39)++-- | Character Variant 40+pattern FEATURE_TAG_cv40 :: FeatureTag+pattern FEATURE_TAG_cv40 = FeatureTag (#const KBTS_FEATURE_TAG_cv40)++-- | Character Variant 41+pattern FEATURE_TAG_cv41 :: FeatureTag+pattern FEATURE_TAG_cv41 = FeatureTag (#const KBTS_FEATURE_TAG_cv41)++-- | Character Variant 42+pattern FEATURE_TAG_cv42 :: FeatureTag+pattern FEATURE_TAG_cv42 = FeatureTag (#const KBTS_FEATURE_TAG_cv42)++-- | Character Variant 43+pattern FEATURE_TAG_cv43 :: FeatureTag+pattern FEATURE_TAG_cv43 = FeatureTag (#const KBTS_FEATURE_TAG_cv43)++-- | Character Variant 44+pattern FEATURE_TAG_cv44 :: FeatureTag+pattern FEATURE_TAG_cv44 = FeatureTag (#const KBTS_FEATURE_TAG_cv44)++-- | Character Variant 45+pattern FEATURE_TAG_cv45 :: FeatureTag+pattern FEATURE_TAG_cv45 = FeatureTag (#const KBTS_FEATURE_TAG_cv45)++-- | Character Variant 46+pattern FEATURE_TAG_cv46 :: FeatureTag+pattern FEATURE_TAG_cv46 = FeatureTag (#const KBTS_FEATURE_TAG_cv46)++-- | Character Variant 47+pattern FEATURE_TAG_cv47 :: FeatureTag+pattern FEATURE_TAG_cv47 = FeatureTag (#const KBTS_FEATURE_TAG_cv47)++-- | Character Variant 48+pattern FEATURE_TAG_cv48 :: FeatureTag+pattern FEATURE_TAG_cv48 = FeatureTag (#const KBTS_FEATURE_TAG_cv48)++-- | Character Variant 49+pattern FEATURE_TAG_cv49 :: FeatureTag+pattern FEATURE_TAG_cv49 = FeatureTag (#const KBTS_FEATURE_TAG_cv49)++-- | Character Variant 50+pattern FEATURE_TAG_cv50 :: FeatureTag+pattern FEATURE_TAG_cv50 = FeatureTag (#const KBTS_FEATURE_TAG_cv50)++-- | Character Variant 51+pattern FEATURE_TAG_cv51 :: FeatureTag+pattern FEATURE_TAG_cv51 = FeatureTag (#const KBTS_FEATURE_TAG_cv51)++-- | Character Variant 52+pattern FEATURE_TAG_cv52 :: FeatureTag+pattern FEATURE_TAG_cv52 = FeatureTag (#const KBTS_FEATURE_TAG_cv52)++-- | Character Variant 53+pattern FEATURE_TAG_cv53 :: FeatureTag+pattern FEATURE_TAG_cv53 = FeatureTag (#const KBTS_FEATURE_TAG_cv53)++-- | Character Variant 54+pattern FEATURE_TAG_cv54 :: FeatureTag+pattern FEATURE_TAG_cv54 = FeatureTag (#const KBTS_FEATURE_TAG_cv54)++-- | Character Variant 55+pattern FEATURE_TAG_cv55 :: FeatureTag+pattern FEATURE_TAG_cv55 = FeatureTag (#const KBTS_FEATURE_TAG_cv55)++-- | Character Variant 56+pattern FEATURE_TAG_cv56 :: FeatureTag+pattern FEATURE_TAG_cv56 = FeatureTag (#const KBTS_FEATURE_TAG_cv56)++-- | Character Variant 57+pattern FEATURE_TAG_cv57 :: FeatureTag+pattern FEATURE_TAG_cv57 = FeatureTag (#const KBTS_FEATURE_TAG_cv57)++-- | Character Variant 58+pattern FEATURE_TAG_cv58 :: FeatureTag+pattern FEATURE_TAG_cv58 = FeatureTag (#const KBTS_FEATURE_TAG_cv58)++-- | Character Variant 59+pattern FEATURE_TAG_cv59 :: FeatureTag+pattern FEATURE_TAG_cv59 = FeatureTag (#const KBTS_FEATURE_TAG_cv59)++-- | Character Variant 60+pattern FEATURE_TAG_cv60 :: FeatureTag+pattern FEATURE_TAG_cv60 = FeatureTag (#const KBTS_FEATURE_TAG_cv60)++-- | Character Variant 61+pattern FEATURE_TAG_cv61 :: FeatureTag+pattern FEATURE_TAG_cv61 = FeatureTag (#const KBTS_FEATURE_TAG_cv61)++-- | Character Variant 62+pattern FEATURE_TAG_cv62 :: FeatureTag+pattern FEATURE_TAG_cv62 = FeatureTag (#const KBTS_FEATURE_TAG_cv62)++-- | Character Variant 63+pattern FEATURE_TAG_cv63 :: FeatureTag+pattern FEATURE_TAG_cv63 = FeatureTag (#const KBTS_FEATURE_TAG_cv63)++-- | Character Variant 64+pattern FEATURE_TAG_cv64 :: FeatureTag+pattern FEATURE_TAG_cv64 = FeatureTag (#const KBTS_FEATURE_TAG_cv64)++-- | Character Variant 65+pattern FEATURE_TAG_cv65 :: FeatureTag+pattern FEATURE_TAG_cv65 = FeatureTag (#const KBTS_FEATURE_TAG_cv65)++-- | Character Variant 66+pattern FEATURE_TAG_cv66 :: FeatureTag+pattern FEATURE_TAG_cv66 = FeatureTag (#const KBTS_FEATURE_TAG_cv66)++-- | Character Variant 67+pattern FEATURE_TAG_cv67 :: FeatureTag+pattern FEATURE_TAG_cv67 = FeatureTag (#const KBTS_FEATURE_TAG_cv67)++-- | Character Variant 68+pattern FEATURE_TAG_cv68 :: FeatureTag+pattern FEATURE_TAG_cv68 = FeatureTag (#const KBTS_FEATURE_TAG_cv68)++-- | Character Variant 69+pattern FEATURE_TAG_cv69 :: FeatureTag+pattern FEATURE_TAG_cv69 = FeatureTag (#const KBTS_FEATURE_TAG_cv69)++-- | Character Variant 70+pattern FEATURE_TAG_cv70 :: FeatureTag+pattern FEATURE_TAG_cv70 = FeatureTag (#const KBTS_FEATURE_TAG_cv70)++-- | Character Variant 71+pattern FEATURE_TAG_cv71 :: FeatureTag+pattern FEATURE_TAG_cv71 = FeatureTag (#const KBTS_FEATURE_TAG_cv71)++-- | Character Variant 72+pattern FEATURE_TAG_cv72 :: FeatureTag+pattern FEATURE_TAG_cv72 = FeatureTag (#const KBTS_FEATURE_TAG_cv72)++-- | Character Variant 73+pattern FEATURE_TAG_cv73 :: FeatureTag+pattern FEATURE_TAG_cv73 = FeatureTag (#const KBTS_FEATURE_TAG_cv73)++-- | Character Variant 74+pattern FEATURE_TAG_cv74 :: FeatureTag+pattern FEATURE_TAG_cv74 = FeatureTag (#const KBTS_FEATURE_TAG_cv74)++-- | Character Variant 75+pattern FEATURE_TAG_cv75 :: FeatureTag+pattern FEATURE_TAG_cv75 = FeatureTag (#const KBTS_FEATURE_TAG_cv75)++-- | Character Variant 76+pattern FEATURE_TAG_cv76 :: FeatureTag+pattern FEATURE_TAG_cv76 = FeatureTag (#const KBTS_FEATURE_TAG_cv76)++-- | Character Variant 77+pattern FEATURE_TAG_cv77 :: FeatureTag+pattern FEATURE_TAG_cv77 = FeatureTag (#const KBTS_FEATURE_TAG_cv77)++-- | Character Variant 78+pattern FEATURE_TAG_cv78 :: FeatureTag+pattern FEATURE_TAG_cv78 = FeatureTag (#const KBTS_FEATURE_TAG_cv78)++-- | Character Variant 79+pattern FEATURE_TAG_cv79 :: FeatureTag+pattern FEATURE_TAG_cv79 = FeatureTag (#const KBTS_FEATURE_TAG_cv79)++-- | Character Variant 80+pattern FEATURE_TAG_cv80 :: FeatureTag+pattern FEATURE_TAG_cv80 = FeatureTag (#const KBTS_FEATURE_TAG_cv80)++-- | Character Variant 81+pattern FEATURE_TAG_cv81 :: FeatureTag+pattern FEATURE_TAG_cv81 = FeatureTag (#const KBTS_FEATURE_TAG_cv81)++-- | Character Variant 82+pattern FEATURE_TAG_cv82 :: FeatureTag+pattern FEATURE_TAG_cv82 = FeatureTag (#const KBTS_FEATURE_TAG_cv82)++-- | Character Variant 83+pattern FEATURE_TAG_cv83 :: FeatureTag+pattern FEATURE_TAG_cv83 = FeatureTag (#const KBTS_FEATURE_TAG_cv83)++-- | Character Variant 84+pattern FEATURE_TAG_cv84 :: FeatureTag+pattern FEATURE_TAG_cv84 = FeatureTag (#const KBTS_FEATURE_TAG_cv84)++-- | Character Variant 85+pattern FEATURE_TAG_cv85 :: FeatureTag+pattern FEATURE_TAG_cv85 = FeatureTag (#const KBTS_FEATURE_TAG_cv85)++-- | Character Variant 86+pattern FEATURE_TAG_cv86 :: FeatureTag+pattern FEATURE_TAG_cv86 = FeatureTag (#const KBTS_FEATURE_TAG_cv86)++-- | Character Variant 87+pattern FEATURE_TAG_cv87 :: FeatureTag+pattern FEATURE_TAG_cv87 = FeatureTag (#const KBTS_FEATURE_TAG_cv87)++-- | Character Variant 88+pattern FEATURE_TAG_cv88 :: FeatureTag+pattern FEATURE_TAG_cv88 = FeatureTag (#const KBTS_FEATURE_TAG_cv88)++-- | Character Variant 89+pattern FEATURE_TAG_cv89 :: FeatureTag+pattern FEATURE_TAG_cv89 = FeatureTag (#const KBTS_FEATURE_TAG_cv89)++-- | Character Variant 90+pattern FEATURE_TAG_cv90 :: FeatureTag+pattern FEATURE_TAG_cv90 = FeatureTag (#const KBTS_FEATURE_TAG_cv90)++-- | Character Variant 91+pattern FEATURE_TAG_cv91 :: FeatureTag+pattern FEATURE_TAG_cv91 = FeatureTag (#const KBTS_FEATURE_TAG_cv91)++-- | Character Variant 92+pattern FEATURE_TAG_cv92 :: FeatureTag+pattern FEATURE_TAG_cv92 = FeatureTag (#const KBTS_FEATURE_TAG_cv92)++-- | Character Variant 93+pattern FEATURE_TAG_cv93 :: FeatureTag+pattern FEATURE_TAG_cv93 = FeatureTag (#const KBTS_FEATURE_TAG_cv93)++-- | Character Variant 94+pattern FEATURE_TAG_cv94 :: FeatureTag+pattern FEATURE_TAG_cv94 = FeatureTag (#const KBTS_FEATURE_TAG_cv94)++-- | Character Variant 95+pattern FEATURE_TAG_cv95 :: FeatureTag+pattern FEATURE_TAG_cv95 = FeatureTag (#const KBTS_FEATURE_TAG_cv95)++-- | Character Variant 96+pattern FEATURE_TAG_cv96 :: FeatureTag+pattern FEATURE_TAG_cv96 = FeatureTag (#const KBTS_FEATURE_TAG_cv96)++-- | Character Variant 97+pattern FEATURE_TAG_cv97 :: FeatureTag+pattern FEATURE_TAG_cv97 = FeatureTag (#const KBTS_FEATURE_TAG_cv97)++-- | Character Variant 98+pattern FEATURE_TAG_cv98 :: FeatureTag+pattern FEATURE_TAG_cv98 = FeatureTag (#const KBTS_FEATURE_TAG_cv98)++-- | Character Variant 99+pattern FEATURE_TAG_cv99 :: FeatureTag+pattern FEATURE_TAG_cv99 = FeatureTag (#const KBTS_FEATURE_TAG_cv99)++-- | Petite Capitals From Capitals+pattern FEATURE_TAG_c2pc :: FeatureTag+pattern FEATURE_TAG_c2pc = FeatureTag (#const KBTS_FEATURE_TAG_c2pc)++-- | Small Capitals From Capitals+pattern FEATURE_TAG_c2sc :: FeatureTag+pattern FEATURE_TAG_c2sc = FeatureTag (#const KBTS_FEATURE_TAG_c2sc)++-- | Distances+pattern FEATURE_TAG_dist :: FeatureTag+pattern FEATURE_TAG_dist = FeatureTag (#const KBTS_FEATURE_TAG_dist)++-- | Discretionary Ligatures+pattern FEATURE_TAG_dlig :: FeatureTag+pattern FEATURE_TAG_dlig = FeatureTag (#const KBTS_FEATURE_TAG_dlig)++-- | Dotless Forms+pattern FEATURE_TAG_dtls :: FeatureTag+pattern FEATURE_TAG_dtls = FeatureTag (#const KBTS_FEATURE_TAG_dtls)++-- | Expert Forms+pattern FEATURE_TAG_expt :: FeatureTag+pattern FEATURE_TAG_expt = FeatureTag (#const KBTS_FEATURE_TAG_expt)++-- | Final Glyph on Line Alternates+pattern FEATURE_TAG_falt :: FeatureTag+pattern FEATURE_TAG_falt = FeatureTag (#const KBTS_FEATURE_TAG_falt)++-- | Flattened Accent Forms+pattern FEATURE_TAG_flac :: FeatureTag+pattern FEATURE_TAG_flac = FeatureTag (#const KBTS_FEATURE_TAG_flac)++-- | Full Widths+pattern FEATURE_TAG_fwid :: FeatureTag+pattern FEATURE_TAG_fwid = FeatureTag (#const KBTS_FEATURE_TAG_fwid)++-- | Halant Forms+pattern FEATURE_TAG_haln :: FeatureTag+pattern FEATURE_TAG_haln = FeatureTag (#const KBTS_FEATURE_TAG_haln)++-- | Alternate Half Widths+pattern FEATURE_TAG_halt :: FeatureTag+pattern FEATURE_TAG_halt = FeatureTag (#const KBTS_FEATURE_TAG_halt)++-- | Historical Forms+pattern FEATURE_TAG_hist :: FeatureTag+pattern FEATURE_TAG_hist = FeatureTag (#const KBTS_FEATURE_TAG_hist)++-- | Horizontal Kana Alternates+pattern FEATURE_TAG_hkna :: FeatureTag+pattern FEATURE_TAG_hkna = FeatureTag (#const KBTS_FEATURE_TAG_hkna)++-- | Historical Ligatures+pattern FEATURE_TAG_hlig :: FeatureTag+pattern FEATURE_TAG_hlig = FeatureTag (#const KBTS_FEATURE_TAG_hlig)++-- | Hangul+pattern FEATURE_TAG_hngl :: FeatureTag+pattern FEATURE_TAG_hngl = FeatureTag (#const KBTS_FEATURE_TAG_hngl)++-- | Hojo Kanji Forms (JIS X 0212-1990 Kanji Forms)+pattern FEATURE_TAG_hojo :: FeatureTag+pattern FEATURE_TAG_hojo = FeatureTag (#const KBTS_FEATURE_TAG_hojo)++-- | Half Widths+pattern FEATURE_TAG_hwid :: FeatureTag+pattern FEATURE_TAG_hwid = FeatureTag (#const KBTS_FEATURE_TAG_hwid)++-- | Italics+pattern FEATURE_TAG_ital :: FeatureTag+pattern FEATURE_TAG_ital = FeatureTag (#const KBTS_FEATURE_TAG_ital)++-- | Justification Alternates+pattern FEATURE_TAG_jalt :: FeatureTag+pattern FEATURE_TAG_jalt = FeatureTag (#const KBTS_FEATURE_TAG_jalt)++-- | JIS78 Forms+pattern FEATURE_TAG_jp78 :: FeatureTag+pattern FEATURE_TAG_jp78 = FeatureTag (#const KBTS_FEATURE_TAG_jp78)++-- | JIS83 Forms+pattern FEATURE_TAG_jp83 :: FeatureTag+pattern FEATURE_TAG_jp83 = FeatureTag (#const KBTS_FEATURE_TAG_jp83)++-- | JIS90 Forms+pattern FEATURE_TAG_jp90 :: FeatureTag+pattern FEATURE_TAG_jp90 = FeatureTag (#const KBTS_FEATURE_TAG_jp90)++-- | JIS2004 Forms+pattern FEATURE_TAG_jp04 :: FeatureTag+pattern FEATURE_TAG_jp04 = FeatureTag (#const KBTS_FEATURE_TAG_jp04)++-- | Kerning+pattern FEATURE_TAG_kern :: FeatureTag+pattern FEATURE_TAG_kern = FeatureTag (#const KBTS_FEATURE_TAG_kern)++-- | Left Bounds+pattern FEATURE_TAG_lfbd :: FeatureTag+pattern FEATURE_TAG_lfbd = FeatureTag (#const KBTS_FEATURE_TAG_lfbd)++-- | Standard Ligatures+pattern FEATURE_TAG_liga :: FeatureTag+pattern FEATURE_TAG_liga = FeatureTag (#const KBTS_FEATURE_TAG_liga)++-- | Lining Figures+pattern FEATURE_TAG_lnum :: FeatureTag+pattern FEATURE_TAG_lnum = FeatureTag (#const KBTS_FEATURE_TAG_lnum)++-- | Localized Forms+pattern FEATURE_TAG_locl :: FeatureTag+pattern FEATURE_TAG_locl = FeatureTag (#const KBTS_FEATURE_TAG_locl)++-- | Left-to-right Alternates+pattern FEATURE_TAG_ltra :: FeatureTag+pattern FEATURE_TAG_ltra = FeatureTag (#const KBTS_FEATURE_TAG_ltra)++-- | Left-to-right Mirrored Forms+pattern FEATURE_TAG_ltrm :: FeatureTag+pattern FEATURE_TAG_ltrm = FeatureTag (#const KBTS_FEATURE_TAG_ltrm)++-- | Mark Positioning+pattern FEATURE_TAG_mark :: FeatureTag+pattern FEATURE_TAG_mark = FeatureTag (#const KBTS_FEATURE_TAG_mark)++-- | Mathematical Greek+pattern FEATURE_TAG_mgrk :: FeatureTag+pattern FEATURE_TAG_mgrk = FeatureTag (#const KBTS_FEATURE_TAG_mgrk)++-- | Mark to Mark Positioning+pattern FEATURE_TAG_mkmk :: FeatureTag+pattern FEATURE_TAG_mkmk = FeatureTag (#const KBTS_FEATURE_TAG_mkmk)++-- | Mark Positioning via Substitution+pattern FEATURE_TAG_mset :: FeatureTag+pattern FEATURE_TAG_mset = FeatureTag (#const KBTS_FEATURE_TAG_mset)++-- | Alternate Annotation Forms+pattern FEATURE_TAG_nalt :: FeatureTag+pattern FEATURE_TAG_nalt = FeatureTag (#const KBTS_FEATURE_TAG_nalt)++-- | NLC Kanji Forms+pattern FEATURE_TAG_nlck :: FeatureTag+pattern FEATURE_TAG_nlck = FeatureTag (#const KBTS_FEATURE_TAG_nlck)++-- | Nukta Forms+pattern FEATURE_TAG_nukt :: FeatureTag+pattern FEATURE_TAG_nukt = FeatureTag (#const KBTS_FEATURE_TAG_nukt)++-- | Oldstyle Figures+pattern FEATURE_TAG_onum :: FeatureTag+pattern FEATURE_TAG_onum = FeatureTag (#const KBTS_FEATURE_TAG_onum)++-- | Optical Bounds+pattern FEATURE_TAG_opbd :: FeatureTag+pattern FEATURE_TAG_opbd = FeatureTag (#const KBTS_FEATURE_TAG_opbd)++-- | Ordinals+pattern FEATURE_TAG_ordn :: FeatureTag+pattern FEATURE_TAG_ordn = FeatureTag (#const KBTS_FEATURE_TAG_ordn)++-- | Ornaments+pattern FEATURE_TAG_ornm :: FeatureTag+pattern FEATURE_TAG_ornm = FeatureTag (#const KBTS_FEATURE_TAG_ornm)++-- | Proportional Alternate Widths+pattern FEATURE_TAG_palt :: FeatureTag+pattern FEATURE_TAG_palt = FeatureTag (#const KBTS_FEATURE_TAG_palt)++-- | Petite Capitals+pattern FEATURE_TAG_pcap :: FeatureTag+pattern FEATURE_TAG_pcap = FeatureTag (#const KBTS_FEATURE_TAG_pcap)++-- | Proportional Kana+pattern FEATURE_TAG_pkna :: FeatureTag+pattern FEATURE_TAG_pkna = FeatureTag (#const KBTS_FEATURE_TAG_pkna)++-- | Proportional Figures+pattern FEATURE_TAG_pnum :: FeatureTag+pattern FEATURE_TAG_pnum = FeatureTag (#const KBTS_FEATURE_TAG_pnum)++-- | Pre-base Substitutions+pattern FEATURE_TAG_pres :: FeatureTag+pattern FEATURE_TAG_pres = FeatureTag (#const KBTS_FEATURE_TAG_pres)++-- | Post-base Substitutions+pattern FEATURE_TAG_psts :: FeatureTag+pattern FEATURE_TAG_psts = FeatureTag (#const KBTS_FEATURE_TAG_psts)++-- | Proportional Widths+pattern FEATURE_TAG_pwid :: FeatureTag+pattern FEATURE_TAG_pwid = FeatureTag (#const KBTS_FEATURE_TAG_pwid)++-- | Quarter Widths+pattern FEATURE_TAG_qwid :: FeatureTag+pattern FEATURE_TAG_qwid = FeatureTag (#const KBTS_FEATURE_TAG_qwid)++-- | Randomize+pattern FEATURE_TAG_rand :: FeatureTag+pattern FEATURE_TAG_rand = FeatureTag (#const KBTS_FEATURE_TAG_rand)++-- | Required Contextual Alternates+pattern FEATURE_TAG_rclt :: FeatureTag+pattern FEATURE_TAG_rclt = FeatureTag (#const KBTS_FEATURE_TAG_rclt)++-- | Rakar Forms+pattern FEATURE_TAG_rkrf :: FeatureTag+pattern FEATURE_TAG_rkrf = FeatureTag (#const KBTS_FEATURE_TAG_rkrf)++-- | Required Ligatures+pattern FEATURE_TAG_rlig :: FeatureTag+pattern FEATURE_TAG_rlig = FeatureTag (#const KBTS_FEATURE_TAG_rlig)++-- | Right Bounds+pattern FEATURE_TAG_rtbd :: FeatureTag+pattern FEATURE_TAG_rtbd = FeatureTag (#const KBTS_FEATURE_TAG_rtbd)++-- | Right-to-left Alternates+pattern FEATURE_TAG_rtla :: FeatureTag+pattern FEATURE_TAG_rtla = FeatureTag (#const KBTS_FEATURE_TAG_rtla)++-- | Right-to-left Mirrored Forms+pattern FEATURE_TAG_rtlm :: FeatureTag+pattern FEATURE_TAG_rtlm = FeatureTag (#const KBTS_FEATURE_TAG_rtlm)++-- | Ruby Notation Forms+pattern FEATURE_TAG_ruby :: FeatureTag+pattern FEATURE_TAG_ruby = FeatureTag (#const KBTS_FEATURE_TAG_ruby)++-- | Required Variation Alternates+pattern FEATURE_TAG_rvrn :: FeatureTag+pattern FEATURE_TAG_rvrn = FeatureTag (#const KBTS_FEATURE_TAG_rvrn)++-- | Stylistic Alternates+pattern FEATURE_TAG_salt :: FeatureTag+pattern FEATURE_TAG_salt = FeatureTag (#const KBTS_FEATURE_TAG_salt)++-- | Scientific Inferiors+pattern FEATURE_TAG_sinf :: FeatureTag+pattern FEATURE_TAG_sinf = FeatureTag (#const KBTS_FEATURE_TAG_sinf)++-- | Optical size+pattern FEATURE_TAG_size :: FeatureTag+pattern FEATURE_TAG_size = FeatureTag (#const KBTS_FEATURE_TAG_size)++-- | Small Capitals+pattern FEATURE_TAG_smcp :: FeatureTag+pattern FEATURE_TAG_smcp = FeatureTag (#const KBTS_FEATURE_TAG_smcp)++-- | Simplified Forms+pattern FEATURE_TAG_smpl :: FeatureTag+pattern FEATURE_TAG_smpl = FeatureTag (#const KBTS_FEATURE_TAG_smpl)++-- | Stylistic Set 1+pattern FEATURE_TAG_ss01 :: FeatureTag+pattern FEATURE_TAG_ss01 = FeatureTag (#const KBTS_FEATURE_TAG_ss01)++-- | Stylistic Set 2+pattern FEATURE_TAG_ss02 :: FeatureTag+pattern FEATURE_TAG_ss02 = FeatureTag (#const KBTS_FEATURE_TAG_ss02)++-- | Stylistic Set 3+pattern FEATURE_TAG_ss03 :: FeatureTag+pattern FEATURE_TAG_ss03 = FeatureTag (#const KBTS_FEATURE_TAG_ss03)++-- | Stylistic Set 4+pattern FEATURE_TAG_ss04 :: FeatureTag+pattern FEATURE_TAG_ss04 = FeatureTag (#const KBTS_FEATURE_TAG_ss04)++-- | Stylistic Set 5+pattern FEATURE_TAG_ss05 :: FeatureTag+pattern FEATURE_TAG_ss05 = FeatureTag (#const KBTS_FEATURE_TAG_ss05)++-- | Stylistic Set 6+pattern FEATURE_TAG_ss06 :: FeatureTag+pattern FEATURE_TAG_ss06 = FeatureTag (#const KBTS_FEATURE_TAG_ss06)++-- | Stylistic Set 7+pattern FEATURE_TAG_ss07 :: FeatureTag+pattern FEATURE_TAG_ss07 = FeatureTag (#const KBTS_FEATURE_TAG_ss07)++-- | Stylistic Set 8+pattern FEATURE_TAG_ss08 :: FeatureTag+pattern FEATURE_TAG_ss08 = FeatureTag (#const KBTS_FEATURE_TAG_ss08)++-- | Stylistic Set 9+pattern FEATURE_TAG_ss09 :: FeatureTag+pattern FEATURE_TAG_ss09 = FeatureTag (#const KBTS_FEATURE_TAG_ss09)++-- | Stylistic Set 10+pattern FEATURE_TAG_ss10 :: FeatureTag+pattern FEATURE_TAG_ss10 = FeatureTag (#const KBTS_FEATURE_TAG_ss10)++-- | Stylistic Set 11+pattern FEATURE_TAG_ss11 :: FeatureTag+pattern FEATURE_TAG_ss11 = FeatureTag (#const KBTS_FEATURE_TAG_ss11)++-- | Stylistic Set 12+pattern FEATURE_TAG_ss12 :: FeatureTag+pattern FEATURE_TAG_ss12 = FeatureTag (#const KBTS_FEATURE_TAG_ss12)++-- | Stylistic Set 13+pattern FEATURE_TAG_ss13 :: FeatureTag+pattern FEATURE_TAG_ss13 = FeatureTag (#const KBTS_FEATURE_TAG_ss13)++-- | Stylistic Set 14+pattern FEATURE_TAG_ss14 :: FeatureTag+pattern FEATURE_TAG_ss14 = FeatureTag (#const KBTS_FEATURE_TAG_ss14)++-- | Stylistic Set 15+pattern FEATURE_TAG_ss15 :: FeatureTag+pattern FEATURE_TAG_ss15 = FeatureTag (#const KBTS_FEATURE_TAG_ss15)++-- | Stylistic Set 16+pattern FEATURE_TAG_ss16 :: FeatureTag+pattern FEATURE_TAG_ss16 = FeatureTag (#const KBTS_FEATURE_TAG_ss16)++-- | Stylistic Set 17+pattern FEATURE_TAG_ss17 :: FeatureTag+pattern FEATURE_TAG_ss17 = FeatureTag (#const KBTS_FEATURE_TAG_ss17)++-- | Stylistic Set 18+pattern FEATURE_TAG_ss18 :: FeatureTag+pattern FEATURE_TAG_ss18 = FeatureTag (#const KBTS_FEATURE_TAG_ss18)++-- | Stylistic Set 19+pattern FEATURE_TAG_ss19 :: FeatureTag+pattern FEATURE_TAG_ss19 = FeatureTag (#const KBTS_FEATURE_TAG_ss19)++-- | Stylistic Set 20+pattern FEATURE_TAG_ss20 :: FeatureTag+pattern FEATURE_TAG_ss20 = FeatureTag (#const KBTS_FEATURE_TAG_ss20)++-- | Math Script-style Alternates+pattern FEATURE_TAG_ssty :: FeatureTag+pattern FEATURE_TAG_ssty = FeatureTag (#const KBTS_FEATURE_TAG_ssty)++-- | Stretching Glyph Decomposition+pattern FEATURE_TAG_stch :: FeatureTag+pattern FEATURE_TAG_stch = FeatureTag (#const KBTS_FEATURE_TAG_stch)++-- | Subscript+pattern FEATURE_TAG_subs :: FeatureTag+pattern FEATURE_TAG_subs = FeatureTag (#const KBTS_FEATURE_TAG_subs)++-- | Superscript+pattern FEATURE_TAG_sups :: FeatureTag+pattern FEATURE_TAG_sups = FeatureTag (#const KBTS_FEATURE_TAG_sups)++-- | Swash+pattern FEATURE_TAG_swsh :: FeatureTag+pattern FEATURE_TAG_swsh = FeatureTag (#const KBTS_FEATURE_TAG_swsh)++-- | Test features, only for development+pattern FEATURE_TAG_test :: FeatureTag+pattern FEATURE_TAG_test = FeatureTag (#const KBTS_FEATURE_TAG_test)++-- | Titling+pattern FEATURE_TAG_titl :: FeatureTag+pattern FEATURE_TAG_titl = FeatureTag (#const KBTS_FEATURE_TAG_titl)++-- | Traditional Name Forms+pattern FEATURE_TAG_tnam :: FeatureTag+pattern FEATURE_TAG_tnam = FeatureTag (#const KBTS_FEATURE_TAG_tnam)++-- | Tabular Figures+pattern FEATURE_TAG_tnum :: FeatureTag+pattern FEATURE_TAG_tnum = FeatureTag (#const KBTS_FEATURE_TAG_tnum)++-- | Traditional Forms+pattern FEATURE_TAG_trad :: FeatureTag+pattern FEATURE_TAG_trad = FeatureTag (#const KBTS_FEATURE_TAG_trad)++-- | Third Widths+pattern FEATURE_TAG_twid :: FeatureTag+pattern FEATURE_TAG_twid = FeatureTag (#const KBTS_FEATURE_TAG_twid)++-- | Unicase+pattern FEATURE_TAG_unic :: FeatureTag+pattern FEATURE_TAG_unic = FeatureTag (#const KBTS_FEATURE_TAG_unic)++-- | Alternate Vertical Metrics+pattern FEATURE_TAG_valt :: FeatureTag+pattern FEATURE_TAG_valt = FeatureTag (#const KBTS_FEATURE_TAG_valt)++-- | Kerning for Alternate Proportional Vertical Metrics+pattern FEATURE_TAG_vapk :: FeatureTag+pattern FEATURE_TAG_vapk = FeatureTag (#const KBTS_FEATURE_TAG_vapk)++-- | Vattu Variants+pattern FEATURE_TAG_vatu :: FeatureTag+pattern FEATURE_TAG_vatu = FeatureTag (#const KBTS_FEATURE_TAG_vatu)++-- | Vertical Contextual Half-width Spacing+pattern FEATURE_TAG_vchw :: FeatureTag+pattern FEATURE_TAG_vchw = FeatureTag (#const KBTS_FEATURE_TAG_vchw)++-- | Vertical Alternates+pattern FEATURE_TAG_vert :: FeatureTag+pattern FEATURE_TAG_vert = FeatureTag (#const KBTS_FEATURE_TAG_vert)++-- | Alternate Vertical Half Metrics+pattern FEATURE_TAG_vhal :: FeatureTag+pattern FEATURE_TAG_vhal = FeatureTag (#const KBTS_FEATURE_TAG_vhal)++-- | Vertical Kana Alternates+pattern FEATURE_TAG_vkna :: FeatureTag+pattern FEATURE_TAG_vkna = FeatureTag (#const KBTS_FEATURE_TAG_vkna)++-- | Vertical Kerning+pattern FEATURE_TAG_vkrn :: FeatureTag+pattern FEATURE_TAG_vkrn = FeatureTag (#const KBTS_FEATURE_TAG_vkrn)++-- | Proportional Alternate Vertical Metrics+pattern FEATURE_TAG_vpal :: FeatureTag+pattern FEATURE_TAG_vpal = FeatureTag (#const KBTS_FEATURE_TAG_vpal)++-- | Vertical Alternates and Rotation+pattern FEATURE_TAG_vrt2 :: FeatureTag+pattern FEATURE_TAG_vrt2 = FeatureTag (#const KBTS_FEATURE_TAG_vrt2)++-- | Vertical Alternates for Rotation+pattern FEATURE_TAG_vrtr :: FeatureTag+pattern FEATURE_TAG_vrtr = FeatureTag (#const KBTS_FEATURE_TAG_vrtr)++-- | Slashed Zero+pattern FEATURE_TAG_zero :: FeatureTag+pattern FEATURE_TAG_zero = FeatureTag (#const KBTS_FEATURE_TAG_zero)++featureTagNames :: Map FeatureTag String+featureTagNames = Map.fromList+ [ (FEATURE_TAG_UNREGISTERED, "FEATURE_TAG_UNREGISTERED")+ , (FEATURE_TAG_isol, "FEATURE_TAG_isol")+ , (FEATURE_TAG_fina, "FEATURE_TAG_fina")+ , (FEATURE_TAG_fin2, "FEATURE_TAG_fin2")+ , (FEATURE_TAG_fin3, "FEATURE_TAG_fin3")+ , (FEATURE_TAG_medi, "FEATURE_TAG_medi")+ , (FEATURE_TAG_med2, "FEATURE_TAG_med2")+ , (FEATURE_TAG_init, "FEATURE_TAG_init")+ , (FEATURE_TAG_ljmo, "FEATURE_TAG_ljmo")+ , (FEATURE_TAG_vjmo, "FEATURE_TAG_vjmo")+ , (FEATURE_TAG_tjmo, "FEATURE_TAG_tjmo")+ , (FEATURE_TAG_rphf, "FEATURE_TAG_rphf")+ , (FEATURE_TAG_blwf, "FEATURE_TAG_blwf")+ , (FEATURE_TAG_half, "FEATURE_TAG_half")+ , (FEATURE_TAG_pstf, "FEATURE_TAG_pstf")+ , (FEATURE_TAG_abvf, "FEATURE_TAG_abvf")+ , (FEATURE_TAG_pref, "FEATURE_TAG_pref")+ , (FEATURE_TAG_numr, "FEATURE_TAG_numr")+ , (FEATURE_TAG_frac, "FEATURE_TAG_frac")+ , (FEATURE_TAG_dnom, "FEATURE_TAG_dnom")+ , (FEATURE_TAG_cfar, "FEATURE_TAG_cfar")+ , (FEATURE_TAG_aalt, "FEATURE_TAG_aalt")+ , (FEATURE_TAG_abvm, "FEATURE_TAG_abvm")+ , (FEATURE_TAG_abvs, "FEATURE_TAG_abvs")+ , (FEATURE_TAG_afrc, "FEATURE_TAG_afrc")+ , (FEATURE_TAG_akhn, "FEATURE_TAG_akhn")+ , (FEATURE_TAG_apkn, "FEATURE_TAG_apkn")+ , (FEATURE_TAG_blwm, "FEATURE_TAG_blwm")+ , (FEATURE_TAG_blws, "FEATURE_TAG_blws")+ , (FEATURE_TAG_calt, "FEATURE_TAG_calt")+ , (FEATURE_TAG_case, "FEATURE_TAG_case")+ , (FEATURE_TAG_ccmp, "FEATURE_TAG_ccmp")+ , (FEATURE_TAG_chws, "FEATURE_TAG_chws")+ , (FEATURE_TAG_cjct, "FEATURE_TAG_cjct")+ , (FEATURE_TAG_clig, "FEATURE_TAG_clig")+ , (FEATURE_TAG_cpct, "FEATURE_TAG_cpct")+ , (FEATURE_TAG_cpsp, "FEATURE_TAG_cpsp")+ , (FEATURE_TAG_cswh, "FEATURE_TAG_cswh")+ , (FEATURE_TAG_curs, "FEATURE_TAG_curs")+ , (FEATURE_TAG_cv01, "FEATURE_TAG_cv01")+ , (FEATURE_TAG_cv02, "FEATURE_TAG_cv02")+ , (FEATURE_TAG_cv03, "FEATURE_TAG_cv03")+ , (FEATURE_TAG_cv04, "FEATURE_TAG_cv04")+ , (FEATURE_TAG_cv05, "FEATURE_TAG_cv05")+ , (FEATURE_TAG_cv06, "FEATURE_TAG_cv06")+ , (FEATURE_TAG_cv07, "FEATURE_TAG_cv07")+ , (FEATURE_TAG_cv08, "FEATURE_TAG_cv08")+ , (FEATURE_TAG_cv09, "FEATURE_TAG_cv09")+ , (FEATURE_TAG_cv10, "FEATURE_TAG_cv10")+ , (FEATURE_TAG_cv11, "FEATURE_TAG_cv11")+ , (FEATURE_TAG_cv12, "FEATURE_TAG_cv12")+ , (FEATURE_TAG_cv13, "FEATURE_TAG_cv13")+ , (FEATURE_TAG_cv14, "FEATURE_TAG_cv14")+ , (FEATURE_TAG_cv15, "FEATURE_TAG_cv15")+ , (FEATURE_TAG_cv16, "FEATURE_TAG_cv16")+ , (FEATURE_TAG_cv17, "FEATURE_TAG_cv17")+ , (FEATURE_TAG_cv18, "FEATURE_TAG_cv18")+ , (FEATURE_TAG_cv19, "FEATURE_TAG_cv19")+ , (FEATURE_TAG_cv20, "FEATURE_TAG_cv20")+ , (FEATURE_TAG_cv21, "FEATURE_TAG_cv21")+ , (FEATURE_TAG_cv22, "FEATURE_TAG_cv22")+ , (FEATURE_TAG_cv23, "FEATURE_TAG_cv23")+ , (FEATURE_TAG_cv24, "FEATURE_TAG_cv24")+ , (FEATURE_TAG_cv25, "FEATURE_TAG_cv25")+ , (FEATURE_TAG_cv26, "FEATURE_TAG_cv26")+ , (FEATURE_TAG_cv27, "FEATURE_TAG_cv27")+ , (FEATURE_TAG_cv28, "FEATURE_TAG_cv28")+ , (FEATURE_TAG_cv29, "FEATURE_TAG_cv29")+ , (FEATURE_TAG_cv30, "FEATURE_TAG_cv30")+ , (FEATURE_TAG_cv31, "FEATURE_TAG_cv31")+ , (FEATURE_TAG_cv32, "FEATURE_TAG_cv32")+ , (FEATURE_TAG_cv33, "FEATURE_TAG_cv33")+ , (FEATURE_TAG_cv34, "FEATURE_TAG_cv34")+ , (FEATURE_TAG_cv35, "FEATURE_TAG_cv35")+ , (FEATURE_TAG_cv36, "FEATURE_TAG_cv36")+ , (FEATURE_TAG_cv37, "FEATURE_TAG_cv37")+ , (FEATURE_TAG_cv38, "FEATURE_TAG_cv38")+ , (FEATURE_TAG_cv39, "FEATURE_TAG_cv39")+ , (FEATURE_TAG_cv40, "FEATURE_TAG_cv40")+ , (FEATURE_TAG_cv41, "FEATURE_TAG_cv41")+ , (FEATURE_TAG_cv42, "FEATURE_TAG_cv42")+ , (FEATURE_TAG_cv43, "FEATURE_TAG_cv43")+ , (FEATURE_TAG_cv44, "FEATURE_TAG_cv44")+ , (FEATURE_TAG_cv45, "FEATURE_TAG_cv45")+ , (FEATURE_TAG_cv46, "FEATURE_TAG_cv46")+ , (FEATURE_TAG_cv47, "FEATURE_TAG_cv47")+ , (FEATURE_TAG_cv48, "FEATURE_TAG_cv48")+ , (FEATURE_TAG_cv49, "FEATURE_TAG_cv49")+ , (FEATURE_TAG_cv50, "FEATURE_TAG_cv50")+ , (FEATURE_TAG_cv51, "FEATURE_TAG_cv51")+ , (FEATURE_TAG_cv52, "FEATURE_TAG_cv52")+ , (FEATURE_TAG_cv53, "FEATURE_TAG_cv53")+ , (FEATURE_TAG_cv54, "FEATURE_TAG_cv54")+ , (FEATURE_TAG_cv55, "FEATURE_TAG_cv55")+ , (FEATURE_TAG_cv56, "FEATURE_TAG_cv56")+ , (FEATURE_TAG_cv57, "FEATURE_TAG_cv57")+ , (FEATURE_TAG_cv58, "FEATURE_TAG_cv58")+ , (FEATURE_TAG_cv59, "FEATURE_TAG_cv59")+ , (FEATURE_TAG_cv60, "FEATURE_TAG_cv60")+ , (FEATURE_TAG_cv61, "FEATURE_TAG_cv61")+ , (FEATURE_TAG_cv62, "FEATURE_TAG_cv62")+ , (FEATURE_TAG_cv63, "FEATURE_TAG_cv63")+ , (FEATURE_TAG_cv64, "FEATURE_TAG_cv64")+ , (FEATURE_TAG_cv65, "FEATURE_TAG_cv65")+ , (FEATURE_TAG_cv66, "FEATURE_TAG_cv66")+ , (FEATURE_TAG_cv67, "FEATURE_TAG_cv67")+ , (FEATURE_TAG_cv68, "FEATURE_TAG_cv68")+ , (FEATURE_TAG_cv69, "FEATURE_TAG_cv69")+ , (FEATURE_TAG_cv70, "FEATURE_TAG_cv70")+ , (FEATURE_TAG_cv71, "FEATURE_TAG_cv71")+ , (FEATURE_TAG_cv72, "FEATURE_TAG_cv72")+ , (FEATURE_TAG_cv73, "FEATURE_TAG_cv73")+ , (FEATURE_TAG_cv74, "FEATURE_TAG_cv74")+ , (FEATURE_TAG_cv75, "FEATURE_TAG_cv75")+ , (FEATURE_TAG_cv76, "FEATURE_TAG_cv76")+ , (FEATURE_TAG_cv77, "FEATURE_TAG_cv77")+ , (FEATURE_TAG_cv78, "FEATURE_TAG_cv78")+ , (FEATURE_TAG_cv79, "FEATURE_TAG_cv79")+ , (FEATURE_TAG_cv80, "FEATURE_TAG_cv80")+ , (FEATURE_TAG_cv81, "FEATURE_TAG_cv81")+ , (FEATURE_TAG_cv82, "FEATURE_TAG_cv82")+ , (FEATURE_TAG_cv83, "FEATURE_TAG_cv83")+ , (FEATURE_TAG_cv84, "FEATURE_TAG_cv84")+ , (FEATURE_TAG_cv85, "FEATURE_TAG_cv85")+ , (FEATURE_TAG_cv86, "FEATURE_TAG_cv86")+ , (FEATURE_TAG_cv87, "FEATURE_TAG_cv87")+ , (FEATURE_TAG_cv88, "FEATURE_TAG_cv88")+ , (FEATURE_TAG_cv89, "FEATURE_TAG_cv89")+ , (FEATURE_TAG_cv90, "FEATURE_TAG_cv90")+ , (FEATURE_TAG_cv91, "FEATURE_TAG_cv91")+ , (FEATURE_TAG_cv92, "FEATURE_TAG_cv92")+ , (FEATURE_TAG_cv93, "FEATURE_TAG_cv93")+ , (FEATURE_TAG_cv94, "FEATURE_TAG_cv94")+ , (FEATURE_TAG_cv95, "FEATURE_TAG_cv95")+ , (FEATURE_TAG_cv96, "FEATURE_TAG_cv96")+ , (FEATURE_TAG_cv97, "FEATURE_TAG_cv97")+ , (FEATURE_TAG_cv98, "FEATURE_TAG_cv98")+ , (FEATURE_TAG_cv99, "FEATURE_TAG_cv99")+ , (FEATURE_TAG_c2pc, "FEATURE_TAG_c2pc")+ , (FEATURE_TAG_c2sc, "FEATURE_TAG_c2sc")+ , (FEATURE_TAG_dist, "FEATURE_TAG_dist")+ , (FEATURE_TAG_dlig, "FEATURE_TAG_dlig")+ , (FEATURE_TAG_dtls, "FEATURE_TAG_dtls")+ , (FEATURE_TAG_expt, "FEATURE_TAG_expt")+ , (FEATURE_TAG_falt, "FEATURE_TAG_falt")+ , (FEATURE_TAG_flac, "FEATURE_TAG_flac")+ , (FEATURE_TAG_fwid, "FEATURE_TAG_fwid")+ , (FEATURE_TAG_haln, "FEATURE_TAG_haln")+ , (FEATURE_TAG_halt, "FEATURE_TAG_halt")+ , (FEATURE_TAG_hist, "FEATURE_TAG_hist")+ , (FEATURE_TAG_hkna, "FEATURE_TAG_hkna")+ , (FEATURE_TAG_hlig, "FEATURE_TAG_hlig")+ , (FEATURE_TAG_hngl, "FEATURE_TAG_hngl")+ , (FEATURE_TAG_hojo, "FEATURE_TAG_hojo")+ , (FEATURE_TAG_hwid, "FEATURE_TAG_hwid")+ , (FEATURE_TAG_ital, "FEATURE_TAG_ital")+ , (FEATURE_TAG_jalt, "FEATURE_TAG_jalt")+ , (FEATURE_TAG_jp78, "FEATURE_TAG_jp78")+ , (FEATURE_TAG_jp83, "FEATURE_TAG_jp83")+ , (FEATURE_TAG_jp90, "FEATURE_TAG_jp90")+ , (FEATURE_TAG_jp04, "FEATURE_TAG_jp04")+ , (FEATURE_TAG_kern, "FEATURE_TAG_kern")+ , (FEATURE_TAG_lfbd, "FEATURE_TAG_lfbd")+ , (FEATURE_TAG_liga, "FEATURE_TAG_liga")+ , (FEATURE_TAG_lnum, "FEATURE_TAG_lnum")+ , (FEATURE_TAG_locl, "FEATURE_TAG_locl")+ , (FEATURE_TAG_ltra, "FEATURE_TAG_ltra")+ , (FEATURE_TAG_ltrm, "FEATURE_TAG_ltrm")+ , (FEATURE_TAG_mark, "FEATURE_TAG_mark")+ , (FEATURE_TAG_mgrk, "FEATURE_TAG_mgrk")+ , (FEATURE_TAG_mkmk, "FEATURE_TAG_mkmk")+ , (FEATURE_TAG_mset, "FEATURE_TAG_mset")+ , (FEATURE_TAG_nalt, "FEATURE_TAG_nalt")+ , (FEATURE_TAG_nlck, "FEATURE_TAG_nlck")+ , (FEATURE_TAG_nukt, "FEATURE_TAG_nukt")+ , (FEATURE_TAG_onum, "FEATURE_TAG_onum")+ , (FEATURE_TAG_opbd, "FEATURE_TAG_opbd")+ , (FEATURE_TAG_ordn, "FEATURE_TAG_ordn")+ , (FEATURE_TAG_ornm, "FEATURE_TAG_ornm")+ , (FEATURE_TAG_palt, "FEATURE_TAG_palt")+ , (FEATURE_TAG_pcap, "FEATURE_TAG_pcap")+ , (FEATURE_TAG_pkna, "FEATURE_TAG_pkna")+ , (FEATURE_TAG_pnum, "FEATURE_TAG_pnum")+ , (FEATURE_TAG_pres, "FEATURE_TAG_pres")+ , (FEATURE_TAG_psts, "FEATURE_TAG_psts")+ , (FEATURE_TAG_pwid, "FEATURE_TAG_pwid")+ , (FEATURE_TAG_qwid, "FEATURE_TAG_qwid")+ , (FEATURE_TAG_rand, "FEATURE_TAG_rand")+ , (FEATURE_TAG_rclt, "FEATURE_TAG_rclt")+ , (FEATURE_TAG_rkrf, "FEATURE_TAG_rkrf")+ , (FEATURE_TAG_rlig, "FEATURE_TAG_rlig")+ , (FEATURE_TAG_rtbd, "FEATURE_TAG_rtbd")+ , (FEATURE_TAG_rtla, "FEATURE_TAG_rtla")+ , (FEATURE_TAG_rtlm, "FEATURE_TAG_rtlm")+ , (FEATURE_TAG_ruby, "FEATURE_TAG_ruby")+ , (FEATURE_TAG_rvrn, "FEATURE_TAG_rvrn")+ , (FEATURE_TAG_salt, "FEATURE_TAG_salt")+ , (FEATURE_TAG_sinf, "FEATURE_TAG_sinf")+ , (FEATURE_TAG_size, "FEATURE_TAG_size")+ , (FEATURE_TAG_smcp, "FEATURE_TAG_smcp")+ , (FEATURE_TAG_smpl, "FEATURE_TAG_smpl")+ , (FEATURE_TAG_ss01, "FEATURE_TAG_ss01")+ , (FEATURE_TAG_ss02, "FEATURE_TAG_ss02")+ , (FEATURE_TAG_ss03, "FEATURE_TAG_ss03")+ , (FEATURE_TAG_ss04, "FEATURE_TAG_ss04")+ , (FEATURE_TAG_ss05, "FEATURE_TAG_ss05")+ , (FEATURE_TAG_ss06, "FEATURE_TAG_ss06")+ , (FEATURE_TAG_ss07, "FEATURE_TAG_ss07")+ , (FEATURE_TAG_ss08, "FEATURE_TAG_ss08")+ , (FEATURE_TAG_ss09, "FEATURE_TAG_ss09")+ , (FEATURE_TAG_ss10, "FEATURE_TAG_ss10")+ , (FEATURE_TAG_ss11, "FEATURE_TAG_ss11")+ , (FEATURE_TAG_ss12, "FEATURE_TAG_ss12")+ , (FEATURE_TAG_ss13, "FEATURE_TAG_ss13")+ , (FEATURE_TAG_ss14, "FEATURE_TAG_ss14")+ , (FEATURE_TAG_ss15, "FEATURE_TAG_ss15")+ , (FEATURE_TAG_ss16, "FEATURE_TAG_ss16")+ , (FEATURE_TAG_ss17, "FEATURE_TAG_ss17")+ , (FEATURE_TAG_ss18, "FEATURE_TAG_ss18")+ , (FEATURE_TAG_ss19, "FEATURE_TAG_ss19")+ , (FEATURE_TAG_ss20, "FEATURE_TAG_ss20")+ , (FEATURE_TAG_ssty, "FEATURE_TAG_ssty")+ , (FEATURE_TAG_stch, "FEATURE_TAG_stch")+ , (FEATURE_TAG_subs, "FEATURE_TAG_subs")+ , (FEATURE_TAG_sups, "FEATURE_TAG_sups")+ , (FEATURE_TAG_swsh, "FEATURE_TAG_swsh")+ , (FEATURE_TAG_test, "FEATURE_TAG_test")+ , (FEATURE_TAG_titl, "FEATURE_TAG_titl")+ , (FEATURE_TAG_tnam, "FEATURE_TAG_tnam")+ , (FEATURE_TAG_tnum, "FEATURE_TAG_tnum")+ , (FEATURE_TAG_trad, "FEATURE_TAG_trad")+ , (FEATURE_TAG_twid, "FEATURE_TAG_twid")+ , (FEATURE_TAG_unic, "FEATURE_TAG_unic")+ , (FEATURE_TAG_valt, "FEATURE_TAG_valt")+ , (FEATURE_TAG_vapk, "FEATURE_TAG_vapk")+ , (FEATURE_TAG_vatu, "FEATURE_TAG_vatu")+ , (FEATURE_TAG_vchw, "FEATURE_TAG_vchw")+ , (FEATURE_TAG_vert, "FEATURE_TAG_vert")+ , (FEATURE_TAG_vhal, "FEATURE_TAG_vhal")+ , (FEATURE_TAG_vkna, "FEATURE_TAG_vkna")+ , (FEATURE_TAG_vkrn, "FEATURE_TAG_vkrn")+ , (FEATURE_TAG_vpal, "FEATURE_TAG_vpal")+ , (FEATURE_TAG_vrt2, "FEATURE_TAG_vrt2")+ , (FEATURE_TAG_vrtr, "FEATURE_TAG_vrtr")+ , (FEATURE_TAG_zero, "FEATURE_TAG_zero")+ ]
+ src/KB/Text/Shape/FFI/Enums/Language.hsc view
@@ -0,0 +1,2759 @@+module KB.Text.Shape.FFI.Enums.Language where++import Prelude hiding (id, error)+import Foreign++import Data.Map (Map)+import Data.Map.Strict qualified as Map++#include "kb_text_shape.h"++newtype Language = Language Word32+ deriving (Eq, Ord)+ deriving newtype (Storable)++instance Show Language where+ showsPrec d l@(Language lv) =+ case Map.lookup l languageNames of+ Just name -> showString name+ Nothing -> showParen (d > 10) $ showString "Language " . showsPrec 11 lv++pattern LANGUAGE_DONT_KNOW :: Language+pattern LANGUAGE_DONT_KNOW = Language (#const KBTS_LANGUAGE_DONT_KNOW)++pattern LANGUAGE_A_HMAO :: Language+pattern LANGUAGE_A_HMAO = Language (#const KBTS_LANGUAGE_A_HMAO)++pattern LANGUAGE_AARI :: Language+pattern LANGUAGE_AARI = Language (#const KBTS_LANGUAGE_AARI)++pattern LANGUAGE_ABAZA :: Language+pattern LANGUAGE_ABAZA = Language (#const KBTS_LANGUAGE_ABAZA)++pattern LANGUAGE_ABKHAZIAN :: Language+pattern LANGUAGE_ABKHAZIAN = Language (#const KBTS_LANGUAGE_ABKHAZIAN)++pattern LANGUAGE_ACHI :: Language+pattern LANGUAGE_ACHI = Language (#const KBTS_LANGUAGE_ACHI)++pattern LANGUAGE_ACHOLI :: Language+pattern LANGUAGE_ACHOLI = Language (#const KBTS_LANGUAGE_ACHOLI)++pattern LANGUAGE_ADYGHE :: Language+pattern LANGUAGE_ADYGHE = Language (#const KBTS_LANGUAGE_ADYGHE)++pattern LANGUAGE_AFAR :: Language+pattern LANGUAGE_AFAR = Language (#const KBTS_LANGUAGE_AFAR)++pattern LANGUAGE_AFRIKAANS :: Language+pattern LANGUAGE_AFRIKAANS = Language (#const KBTS_LANGUAGE_AFRIKAANS)++pattern LANGUAGE_AGAW :: Language+pattern LANGUAGE_AGAW = Language (#const KBTS_LANGUAGE_AGAW)++pattern LANGUAGE_AITON :: Language+pattern LANGUAGE_AITON = Language (#const KBTS_LANGUAGE_AITON)++pattern LANGUAGE_AKAN :: Language+pattern LANGUAGE_AKAN = Language (#const KBTS_LANGUAGE_AKAN)++pattern LANGUAGE_ALBANIAN :: Language+pattern LANGUAGE_ALBANIAN = Language (#const KBTS_LANGUAGE_ALBANIAN)++pattern LANGUAGE_ALSATIAN :: Language+pattern LANGUAGE_ALSATIAN = Language (#const KBTS_LANGUAGE_ALSATIAN)++pattern LANGUAGE_ALTAI :: Language+pattern LANGUAGE_ALTAI = Language (#const KBTS_LANGUAGE_ALTAI)++pattern LANGUAGE_ALUO :: Language+pattern LANGUAGE_ALUO = Language (#const KBTS_LANGUAGE_ALUO)++pattern LANGUAGE_AMERICAN_PHONETIC :: Language+pattern LANGUAGE_AMERICAN_PHONETIC = Language (#const KBTS_LANGUAGE_AMERICAN_PHONETIC)++pattern LANGUAGE_AMHARIC :: Language+pattern LANGUAGE_AMHARIC = Language (#const KBTS_LANGUAGE_AMHARIC)++pattern LANGUAGE_ANGLO_SAXON :: Language+pattern LANGUAGE_ANGLO_SAXON = Language (#const KBTS_LANGUAGE_ANGLO_SAXON)++pattern LANGUAGE_ARABIC :: Language+pattern LANGUAGE_ARABIC = Language (#const KBTS_LANGUAGE_ARABIC)++pattern LANGUAGE_ARAGONESE :: Language+pattern LANGUAGE_ARAGONESE = Language (#const KBTS_LANGUAGE_ARAGONESE)++pattern LANGUAGE_ARAKANESE :: Language+pattern LANGUAGE_ARAKANESE = Language (#const KBTS_LANGUAGE_ARAKANESE)++pattern LANGUAGE_ARAKWAL :: Language+pattern LANGUAGE_ARAKWAL = Language (#const KBTS_LANGUAGE_ARAKWAL)++pattern LANGUAGE_ARMENIAN :: Language+pattern LANGUAGE_ARMENIAN = Language (#const KBTS_LANGUAGE_ARMENIAN)++pattern LANGUAGE_ARMENIAN_EAST :: Language+pattern LANGUAGE_ARMENIAN_EAST = Language (#const KBTS_LANGUAGE_ARMENIAN_EAST)++pattern LANGUAGE_AROMANIAN :: Language+pattern LANGUAGE_AROMANIAN = Language (#const KBTS_LANGUAGE_AROMANIAN)++pattern LANGUAGE_ARPITAN :: Language+pattern LANGUAGE_ARPITAN = Language (#const KBTS_LANGUAGE_ARPITAN)++pattern LANGUAGE_ASSAMESE :: Language+pattern LANGUAGE_ASSAMESE = Language (#const KBTS_LANGUAGE_ASSAMESE)++pattern LANGUAGE_ASTURIAN :: Language+pattern LANGUAGE_ASTURIAN = Language (#const KBTS_LANGUAGE_ASTURIAN)++pattern LANGUAGE_ATHAPASKAN :: Language+pattern LANGUAGE_ATHAPASKAN = Language (#const KBTS_LANGUAGE_ATHAPASKAN)++pattern LANGUAGE_ATSINA :: Language+pattern LANGUAGE_ATSINA = Language (#const KBTS_LANGUAGE_ATSINA)++pattern LANGUAGE_AVAR :: Language+pattern LANGUAGE_AVAR = Language (#const KBTS_LANGUAGE_AVAR)++pattern LANGUAGE_AVATIME :: Language+pattern LANGUAGE_AVATIME = Language (#const KBTS_LANGUAGE_AVATIME)++pattern LANGUAGE_AWADHI :: Language+pattern LANGUAGE_AWADHI = Language (#const KBTS_LANGUAGE_AWADHI)++pattern LANGUAGE_AYMARA :: Language+pattern LANGUAGE_AYMARA = Language (#const KBTS_LANGUAGE_AYMARA)++pattern LANGUAGE_AZERBAIDJANI :: Language+pattern LANGUAGE_AZERBAIDJANI = Language (#const KBTS_LANGUAGE_AZERBAIDJANI)++pattern LANGUAGE_BADAGA :: Language+pattern LANGUAGE_BADAGA = Language (#const KBTS_LANGUAGE_BADAGA)++pattern LANGUAGE_BAGHELKHANDI :: Language+pattern LANGUAGE_BAGHELKHANDI = Language (#const KBTS_LANGUAGE_BAGHELKHANDI)++pattern LANGUAGE_BAGRI :: Language+pattern LANGUAGE_BAGRI = Language (#const KBTS_LANGUAGE_BAGRI)++pattern LANGUAGE_BALANTE :: Language+pattern LANGUAGE_BALANTE = Language (#const KBTS_LANGUAGE_BALANTE)++pattern LANGUAGE_BALINESE :: Language+pattern LANGUAGE_BALINESE = Language (#const KBTS_LANGUAGE_BALINESE)++pattern LANGUAGE_BALKAR :: Language+pattern LANGUAGE_BALKAR = Language (#const KBTS_LANGUAGE_BALKAR)++pattern LANGUAGE_BALTI :: Language+pattern LANGUAGE_BALTI = Language (#const KBTS_LANGUAGE_BALTI)++pattern LANGUAGE_BALUCHI :: Language+pattern LANGUAGE_BALUCHI = Language (#const KBTS_LANGUAGE_BALUCHI)++pattern LANGUAGE_BAMBARA :: Language+pattern LANGUAGE_BAMBARA = Language (#const KBTS_LANGUAGE_BAMBARA)++pattern LANGUAGE_BAMILEKE :: Language+pattern LANGUAGE_BAMILEKE = Language (#const KBTS_LANGUAGE_BAMILEKE)++pattern LANGUAGE_BANDA :: Language+pattern LANGUAGE_BANDA = Language (#const KBTS_LANGUAGE_BANDA)++pattern LANGUAGE_BANDJALANG :: Language+pattern LANGUAGE_BANDJALANG = Language (#const KBTS_LANGUAGE_BANDJALANG)++pattern LANGUAGE_BANGLA :: Language+pattern LANGUAGE_BANGLA = Language (#const KBTS_LANGUAGE_BANGLA)++pattern LANGUAGE_BASHKIR :: Language+pattern LANGUAGE_BASHKIR = Language (#const KBTS_LANGUAGE_BASHKIR)++pattern LANGUAGE_BASQUE :: Language+pattern LANGUAGE_BASQUE = Language (#const KBTS_LANGUAGE_BASQUE)++pattern LANGUAGE_BATAK :: Language+pattern LANGUAGE_BATAK = Language (#const KBTS_LANGUAGE_BATAK)++pattern LANGUAGE_BATAK_ALAS_KLUET :: Language+pattern LANGUAGE_BATAK_ALAS_KLUET = Language (#const KBTS_LANGUAGE_BATAK_ALAS_KLUET)++pattern LANGUAGE_BATAK_ANGKOLA :: Language+pattern LANGUAGE_BATAK_ANGKOLA = Language (#const KBTS_LANGUAGE_BATAK_ANGKOLA)++pattern LANGUAGE_BATAK_DAIRI :: Language+pattern LANGUAGE_BATAK_DAIRI = Language (#const KBTS_LANGUAGE_BATAK_DAIRI)++pattern LANGUAGE_BATAK_KARO :: Language+pattern LANGUAGE_BATAK_KARO = Language (#const KBTS_LANGUAGE_BATAK_KARO)++pattern LANGUAGE_BATAK_MANDAILING :: Language+pattern LANGUAGE_BATAK_MANDAILING = Language (#const KBTS_LANGUAGE_BATAK_MANDAILING)++pattern LANGUAGE_BATAK_SIMALUNGUN :: Language+pattern LANGUAGE_BATAK_SIMALUNGUN = Language (#const KBTS_LANGUAGE_BATAK_SIMALUNGUN)++pattern LANGUAGE_BATAK_TOBA :: Language+pattern LANGUAGE_BATAK_TOBA = Language (#const KBTS_LANGUAGE_BATAK_TOBA)++pattern LANGUAGE_BAULE :: Language+pattern LANGUAGE_BAULE = Language (#const KBTS_LANGUAGE_BAULE)++pattern LANGUAGE_BAVARIAN :: Language+pattern LANGUAGE_BAVARIAN = Language (#const KBTS_LANGUAGE_BAVARIAN)++pattern LANGUAGE_BELARUSIAN :: Language+pattern LANGUAGE_BELARUSIAN = Language (#const KBTS_LANGUAGE_BELARUSIAN)++pattern LANGUAGE_BEMBA :: Language+pattern LANGUAGE_BEMBA = Language (#const KBTS_LANGUAGE_BEMBA)++pattern LANGUAGE_BENCH :: Language+pattern LANGUAGE_BENCH = Language (#const KBTS_LANGUAGE_BENCH)++pattern LANGUAGE_BERBER :: Language+pattern LANGUAGE_BERBER = Language (#const KBTS_LANGUAGE_BERBER)++pattern LANGUAGE_BETI :: Language+pattern LANGUAGE_BETI = Language (#const KBTS_LANGUAGE_BETI)++pattern LANGUAGE_BETTE_KURUMA :: Language+pattern LANGUAGE_BETTE_KURUMA = Language (#const KBTS_LANGUAGE_BETTE_KURUMA)++pattern LANGUAGE_BHILI :: Language+pattern LANGUAGE_BHILI = Language (#const KBTS_LANGUAGE_BHILI)++pattern LANGUAGE_BHOJPURI :: Language+pattern LANGUAGE_BHOJPURI = Language (#const KBTS_LANGUAGE_BHOJPURI)++pattern LANGUAGE_BHUTANESE :: Language+pattern LANGUAGE_BHUTANESE = Language (#const KBTS_LANGUAGE_BHUTANESE)++pattern LANGUAGE_BIBLE_CREE :: Language+pattern LANGUAGE_BIBLE_CREE = Language (#const KBTS_LANGUAGE_BIBLE_CREE)++pattern LANGUAGE_BIKOL :: Language+pattern LANGUAGE_BIKOL = Language (#const KBTS_LANGUAGE_BIKOL)++pattern LANGUAGE_BILEN :: Language+pattern LANGUAGE_BILEN = Language (#const KBTS_LANGUAGE_BILEN)++pattern LANGUAGE_BISHNUPRIYA_MANIPURI :: Language+pattern LANGUAGE_BISHNUPRIYA_MANIPURI = Language (#const KBTS_LANGUAGE_BISHNUPRIYA_MANIPURI)++pattern LANGUAGE_BISLAMA :: Language+pattern LANGUAGE_BISLAMA = Language (#const KBTS_LANGUAGE_BISLAMA)++pattern LANGUAGE_BLACKFOOT :: Language+pattern LANGUAGE_BLACKFOOT = Language (#const KBTS_LANGUAGE_BLACKFOOT)++pattern LANGUAGE_BODO :: Language+pattern LANGUAGE_BODO = Language (#const KBTS_LANGUAGE_BODO)++pattern LANGUAGE_BOSNIAN :: Language+pattern LANGUAGE_BOSNIAN = Language (#const KBTS_LANGUAGE_BOSNIAN)++pattern LANGUAGE_BOUYEI :: Language+pattern LANGUAGE_BOUYEI = Language (#const KBTS_LANGUAGE_BOUYEI)++pattern LANGUAGE_BRAHUI :: Language+pattern LANGUAGE_BRAHUI = Language (#const KBTS_LANGUAGE_BRAHUI)++pattern LANGUAGE_BRAJ_BHASHA :: Language+pattern LANGUAGE_BRAJ_BHASHA = Language (#const KBTS_LANGUAGE_BRAJ_BHASHA)++pattern LANGUAGE_BRETON :: Language+pattern LANGUAGE_BRETON = Language (#const KBTS_LANGUAGE_BRETON)++pattern LANGUAGE_BUGIS :: Language+pattern LANGUAGE_BUGIS = Language (#const KBTS_LANGUAGE_BUGIS)++pattern LANGUAGE_BULGARIAN :: Language+pattern LANGUAGE_BULGARIAN = Language (#const KBTS_LANGUAGE_BULGARIAN)++pattern LANGUAGE_BUMTHANGKHA :: Language+pattern LANGUAGE_BUMTHANGKHA = Language (#const KBTS_LANGUAGE_BUMTHANGKHA)++pattern LANGUAGE_BURMESE :: Language+pattern LANGUAGE_BURMESE = Language (#const KBTS_LANGUAGE_BURMESE)++pattern LANGUAGE_BURUSHASKI :: Language+pattern LANGUAGE_BURUSHASKI = Language (#const KBTS_LANGUAGE_BURUSHASKI)++pattern LANGUAGE_CAJUN_FRENCH :: Language+pattern LANGUAGE_CAJUN_FRENCH = Language (#const KBTS_LANGUAGE_CAJUN_FRENCH)++pattern LANGUAGE_CARRIER :: Language+pattern LANGUAGE_CARRIER = Language (#const KBTS_LANGUAGE_CARRIER)++pattern LANGUAGE_CATALAN :: Language+pattern LANGUAGE_CATALAN = Language (#const KBTS_LANGUAGE_CATALAN)++pattern LANGUAGE_CAYUGA :: Language+pattern LANGUAGE_CAYUGA = Language (#const KBTS_LANGUAGE_CAYUGA)++pattern LANGUAGE_CEBUANO :: Language+pattern LANGUAGE_CEBUANO = Language (#const KBTS_LANGUAGE_CEBUANO)++pattern LANGUAGE_CENTRAL_YUPIK :: Language+pattern LANGUAGE_CENTRAL_YUPIK = Language (#const KBTS_LANGUAGE_CENTRAL_YUPIK)++pattern LANGUAGE_CHAHA_GURAGE :: Language+pattern LANGUAGE_CHAHA_GURAGE = Language (#const KBTS_LANGUAGE_CHAHA_GURAGE)++pattern LANGUAGE_CHAMORRO :: Language+pattern LANGUAGE_CHAMORRO = Language (#const KBTS_LANGUAGE_CHAMORRO)++pattern LANGUAGE_CHATTISGARHI :: Language+pattern LANGUAGE_CHATTISGARHI = Language (#const KBTS_LANGUAGE_CHATTISGARHI)++pattern LANGUAGE_CHECHEN :: Language+pattern LANGUAGE_CHECHEN = Language (#const KBTS_LANGUAGE_CHECHEN)++pattern LANGUAGE_CHEROKEE :: Language+pattern LANGUAGE_CHEROKEE = Language (#const KBTS_LANGUAGE_CHEROKEE)++pattern LANGUAGE_CHEYENNE :: Language+pattern LANGUAGE_CHEYENNE = Language (#const KBTS_LANGUAGE_CHEYENNE)++pattern LANGUAGE_CHICHEWA :: Language+pattern LANGUAGE_CHICHEWA = Language (#const KBTS_LANGUAGE_CHICHEWA)++pattern LANGUAGE_CHIGA :: Language+pattern LANGUAGE_CHIGA = Language (#const KBTS_LANGUAGE_CHIGA)++pattern LANGUAGE_CHIMILA :: Language+pattern LANGUAGE_CHIMILA = Language (#const KBTS_LANGUAGE_CHIMILA)++pattern LANGUAGE_CHIN :: Language+pattern LANGUAGE_CHIN = Language (#const KBTS_LANGUAGE_CHIN)++pattern LANGUAGE_CHINANTEC :: Language+pattern LANGUAGE_CHINANTEC = Language (#const KBTS_LANGUAGE_CHINANTEC)++pattern LANGUAGE_CHINESE_PHONETIC :: Language+pattern LANGUAGE_CHINESE_PHONETIC = Language (#const KBTS_LANGUAGE_CHINESE_PHONETIC)++pattern LANGUAGE_CHINESE_SIMPLIFIED :: Language+pattern LANGUAGE_CHINESE_SIMPLIFIED = Language (#const KBTS_LANGUAGE_CHINESE_SIMPLIFIED)++pattern LANGUAGE_CHINESE_TRADITIONAL :: Language+pattern LANGUAGE_CHINESE_TRADITIONAL = Language (#const KBTS_LANGUAGE_CHINESE_TRADITIONAL)++pattern LANGUAGE_CHINESE_TRADITIONAL_HONG_KONG :: Language+pattern LANGUAGE_CHINESE_TRADITIONAL_HONG_KONG = Language (#const KBTS_LANGUAGE_CHINESE_TRADITIONAL_HONG_KONG)++pattern LANGUAGE_CHINESE_TRADITIONAL_MACAO :: Language+pattern LANGUAGE_CHINESE_TRADITIONAL_MACAO = Language (#const KBTS_LANGUAGE_CHINESE_TRADITIONAL_MACAO)++pattern LANGUAGE_CHIPEWYAN :: Language+pattern LANGUAGE_CHIPEWYAN = Language (#const KBTS_LANGUAGE_CHIPEWYAN)++pattern LANGUAGE_CHITTAGONIAN :: Language+pattern LANGUAGE_CHITTAGONIAN = Language (#const KBTS_LANGUAGE_CHITTAGONIAN)++pattern LANGUAGE_CHOCTAW :: Language+pattern LANGUAGE_CHOCTAW = Language (#const KBTS_LANGUAGE_CHOCTAW)++pattern LANGUAGE_CHUKCHI :: Language+pattern LANGUAGE_CHUKCHI = Language (#const KBTS_LANGUAGE_CHUKCHI)++pattern LANGUAGE_CHURCH_SLAVONIC :: Language+pattern LANGUAGE_CHURCH_SLAVONIC = Language (#const KBTS_LANGUAGE_CHURCH_SLAVONIC)++pattern LANGUAGE_CHUUKESE :: Language+pattern LANGUAGE_CHUUKESE = Language (#const KBTS_LANGUAGE_CHUUKESE)++pattern LANGUAGE_CHUVASH :: Language+pattern LANGUAGE_CHUVASH = Language (#const KBTS_LANGUAGE_CHUVASH)++pattern LANGUAGE_COMORIAN :: Language+pattern LANGUAGE_COMORIAN = Language (#const KBTS_LANGUAGE_COMORIAN)++pattern LANGUAGE_COMOX :: Language+pattern LANGUAGE_COMOX = Language (#const KBTS_LANGUAGE_COMOX)++pattern LANGUAGE_COPTIC :: Language+pattern LANGUAGE_COPTIC = Language (#const KBTS_LANGUAGE_COPTIC)++pattern LANGUAGE_CORNISH :: Language+pattern LANGUAGE_CORNISH = Language (#const KBTS_LANGUAGE_CORNISH)++pattern LANGUAGE_CORSICAN :: Language+pattern LANGUAGE_CORSICAN = Language (#const KBTS_LANGUAGE_CORSICAN)++pattern LANGUAGE_CREE :: Language+pattern LANGUAGE_CREE = Language (#const KBTS_LANGUAGE_CREE)++pattern LANGUAGE_CREOLES :: Language+pattern LANGUAGE_CREOLES = Language (#const KBTS_LANGUAGE_CREOLES)++pattern LANGUAGE_CRIMEAN_TATAR :: Language+pattern LANGUAGE_CRIMEAN_TATAR = Language (#const KBTS_LANGUAGE_CRIMEAN_TATAR)++pattern LANGUAGE_CRIOULO :: Language+pattern LANGUAGE_CRIOULO = Language (#const KBTS_LANGUAGE_CRIOULO)++pattern LANGUAGE_CROATIAN :: Language+pattern LANGUAGE_CROATIAN = Language (#const KBTS_LANGUAGE_CROATIAN)++pattern LANGUAGE_CYPRIOT_ARABIC :: Language+pattern LANGUAGE_CYPRIOT_ARABIC = Language (#const KBTS_LANGUAGE_CYPRIOT_ARABIC)++pattern LANGUAGE_CZECH :: Language+pattern LANGUAGE_CZECH = Language (#const KBTS_LANGUAGE_CZECH)++pattern LANGUAGE_DAGBANI :: Language+pattern LANGUAGE_DAGBANI = Language (#const KBTS_LANGUAGE_DAGBANI)++pattern LANGUAGE_DAN :: Language+pattern LANGUAGE_DAN = Language (#const KBTS_LANGUAGE_DAN)++pattern LANGUAGE_DANGME :: Language+pattern LANGUAGE_DANGME = Language (#const KBTS_LANGUAGE_DANGME)++pattern LANGUAGE_DANISH :: Language+pattern LANGUAGE_DANISH = Language (#const KBTS_LANGUAGE_DANISH)++pattern LANGUAGE_DARGWA :: Language+pattern LANGUAGE_DARGWA = Language (#const KBTS_LANGUAGE_DARGWA)++pattern LANGUAGE_DARI :: Language+pattern LANGUAGE_DARI = Language (#const KBTS_LANGUAGE_DARI)++pattern LANGUAGE_DAYI :: Language+pattern LANGUAGE_DAYI = Language (#const KBTS_LANGUAGE_DAYI)++pattern LANGUAGE_DEFAULT :: Language+pattern LANGUAGE_DEFAULT = Language (#const KBTS_LANGUAGE_DEFAULT)++pattern LANGUAGE_DEHONG_DAI :: Language+pattern LANGUAGE_DEHONG_DAI = Language (#const KBTS_LANGUAGE_DEHONG_DAI)++pattern LANGUAGE_DHANGU :: Language+pattern LANGUAGE_DHANGU = Language (#const KBTS_LANGUAGE_DHANGU)++pattern LANGUAGE_DHIVEHI :: Language+pattern LANGUAGE_DHIVEHI = Language (#const KBTS_LANGUAGE_DHIVEHI)++pattern LANGUAGE_DHUWAL :: Language+pattern LANGUAGE_DHUWAL = Language (#const KBTS_LANGUAGE_DHUWAL)++pattern LANGUAGE_DIMLI :: Language+pattern LANGUAGE_DIMLI = Language (#const KBTS_LANGUAGE_DIMLI)++pattern LANGUAGE_DINKA :: Language+pattern LANGUAGE_DINKA = Language (#const KBTS_LANGUAGE_DINKA)++pattern LANGUAGE_DIVEHI :: Language+pattern LANGUAGE_DIVEHI = Language (#const KBTS_LANGUAGE_DIVEHI)++pattern LANGUAGE_DJAMBARRPUYNGU :: Language+pattern LANGUAGE_DJAMBARRPUYNGU = Language (#const KBTS_LANGUAGE_DJAMBARRPUYNGU)++pattern LANGUAGE_DOGRI :: Language+pattern LANGUAGE_DOGRI = Language (#const KBTS_LANGUAGE_DOGRI)++pattern LANGUAGE_DOGRI_MACROLANGUAGE :: Language+pattern LANGUAGE_DOGRI_MACROLANGUAGE = Language (#const KBTS_LANGUAGE_DOGRI_MACROLANGUAGE)++pattern LANGUAGE_DUNGAN :: Language+pattern LANGUAGE_DUNGAN = Language (#const KBTS_LANGUAGE_DUNGAN)++pattern LANGUAGE_DUTCH :: Language+pattern LANGUAGE_DUTCH = Language (#const KBTS_LANGUAGE_DUTCH)++pattern LANGUAGE_DZONGKHA :: Language+pattern LANGUAGE_DZONGKHA = Language (#const KBTS_LANGUAGE_DZONGKHA)++pattern LANGUAGE_EASTERN_ABENAKI :: Language+pattern LANGUAGE_EASTERN_ABENAKI = Language (#const KBTS_LANGUAGE_EASTERN_ABENAKI)++pattern LANGUAGE_EASTERN_CHAM :: Language+pattern LANGUAGE_EASTERN_CHAM = Language (#const KBTS_LANGUAGE_EASTERN_CHAM)++pattern LANGUAGE_EASTERN_CREE :: Language+pattern LANGUAGE_EASTERN_CREE = Language (#const KBTS_LANGUAGE_EASTERN_CREE)++pattern LANGUAGE_EASTERN_MANINKAKAN :: Language+pattern LANGUAGE_EASTERN_MANINKAKAN = Language (#const KBTS_LANGUAGE_EASTERN_MANINKAKAN)++pattern LANGUAGE_EASTERN_PWO_KAREN :: Language+pattern LANGUAGE_EASTERN_PWO_KAREN = Language (#const KBTS_LANGUAGE_EASTERN_PWO_KAREN)++pattern LANGUAGE_EBIRA :: Language+pattern LANGUAGE_EBIRA = Language (#const KBTS_LANGUAGE_EBIRA)++pattern LANGUAGE_EDO :: Language+pattern LANGUAGE_EDO = Language (#const KBTS_LANGUAGE_EDO)++pattern LANGUAGE_EFIK :: Language+pattern LANGUAGE_EFIK = Language (#const KBTS_LANGUAGE_EFIK)++pattern LANGUAGE_EMBERA_BAUDO :: Language+pattern LANGUAGE_EMBERA_BAUDO = Language (#const KBTS_LANGUAGE_EMBERA_BAUDO)++pattern LANGUAGE_EMBERA_CATIO :: Language+pattern LANGUAGE_EMBERA_CATIO = Language (#const KBTS_LANGUAGE_EMBERA_CATIO)++pattern LANGUAGE_EMBERA_CHAMI :: Language+pattern LANGUAGE_EMBERA_CHAMI = Language (#const KBTS_LANGUAGE_EMBERA_CHAMI)++pattern LANGUAGE_EMBERA_TADO :: Language+pattern LANGUAGE_EMBERA_TADO = Language (#const KBTS_LANGUAGE_EMBERA_TADO)++pattern LANGUAGE_ENGLISH :: Language+pattern LANGUAGE_ENGLISH = Language (#const KBTS_LANGUAGE_ENGLISH)++pattern LANGUAGE_EPENA :: Language+pattern LANGUAGE_EPENA = Language (#const KBTS_LANGUAGE_EPENA)++pattern LANGUAGE_ERZYA :: Language+pattern LANGUAGE_ERZYA = Language (#const KBTS_LANGUAGE_ERZYA)++pattern LANGUAGE_KB_TEXT_SHAPEANTO :: Language+pattern LANGUAGE_KB_TEXT_SHAPEANTO = Language (#const KBTS_LANGUAGE_KB_TEXT_SHAPEANTO)++pattern LANGUAGE_ESTONIAN :: Language+pattern LANGUAGE_ESTONIAN = Language (#const KBTS_LANGUAGE_ESTONIAN)++pattern LANGUAGE_EVEN :: Language+pattern LANGUAGE_EVEN = Language (#const KBTS_LANGUAGE_EVEN)++pattern LANGUAGE_EVENKI :: Language+pattern LANGUAGE_EVENKI = Language (#const KBTS_LANGUAGE_EVENKI)++pattern LANGUAGE_EWE :: Language+pattern LANGUAGE_EWE = Language (#const KBTS_LANGUAGE_EWE)++pattern LANGUAGE_FALAM_CHIN :: Language+pattern LANGUAGE_FALAM_CHIN = Language (#const KBTS_LANGUAGE_FALAM_CHIN)++pattern LANGUAGE_FANG :: Language+pattern LANGUAGE_FANG = Language (#const KBTS_LANGUAGE_FANG)++pattern LANGUAGE_FANTI :: Language+pattern LANGUAGE_FANTI = Language (#const KBTS_LANGUAGE_FANTI)++pattern LANGUAGE_FAROESE :: Language+pattern LANGUAGE_FAROESE = Language (#const KBTS_LANGUAGE_FAROESE)++pattern LANGUAGE_FEFE :: Language+pattern LANGUAGE_FEFE = Language (#const KBTS_LANGUAGE_FEFE)++pattern LANGUAGE_FIJIAN :: Language+pattern LANGUAGE_FIJIAN = Language (#const KBTS_LANGUAGE_FIJIAN)++pattern LANGUAGE_FILIPINO :: Language+pattern LANGUAGE_FILIPINO = Language (#const KBTS_LANGUAGE_FILIPINO)++pattern LANGUAGE_FINNISH :: Language+pattern LANGUAGE_FINNISH = Language (#const KBTS_LANGUAGE_FINNISH)++pattern LANGUAGE_FLEMISH :: Language+pattern LANGUAGE_FLEMISH = Language (#const KBTS_LANGUAGE_FLEMISH)++pattern LANGUAGE_FON :: Language+pattern LANGUAGE_FON = Language (#const KBTS_LANGUAGE_FON)++pattern LANGUAGE_FOREST_ENETS :: Language+pattern LANGUAGE_FOREST_ENETS = Language (#const KBTS_LANGUAGE_FOREST_ENETS)++pattern LANGUAGE_FRENCH :: Language+pattern LANGUAGE_FRENCH = Language (#const KBTS_LANGUAGE_FRENCH)++pattern LANGUAGE_FRENCH_ANTILLEAN :: Language+pattern LANGUAGE_FRENCH_ANTILLEAN = Language (#const KBTS_LANGUAGE_FRENCH_ANTILLEAN)++pattern LANGUAGE_FRISIAN :: Language+pattern LANGUAGE_FRISIAN = Language (#const KBTS_LANGUAGE_FRISIAN)++pattern LANGUAGE_FRIULIAN :: Language+pattern LANGUAGE_FRIULIAN = Language (#const KBTS_LANGUAGE_FRIULIAN)++pattern LANGUAGE_FULAH :: Language+pattern LANGUAGE_FULAH = Language (#const KBTS_LANGUAGE_FULAH)++pattern LANGUAGE_FUTA :: Language+pattern LANGUAGE_FUTA = Language (#const KBTS_LANGUAGE_FUTA)++pattern LANGUAGE_GA :: Language+pattern LANGUAGE_GA = Language (#const KBTS_LANGUAGE_GA)++pattern LANGUAGE_GAGAUZ :: Language+pattern LANGUAGE_GAGAUZ = Language (#const KBTS_LANGUAGE_GAGAUZ)++pattern LANGUAGE_GALICIAN :: Language+pattern LANGUAGE_GALICIAN = Language (#const KBTS_LANGUAGE_GALICIAN)++pattern LANGUAGE_GANDA :: Language+pattern LANGUAGE_GANDA = Language (#const KBTS_LANGUAGE_GANDA)++pattern LANGUAGE_GARHWALI :: Language+pattern LANGUAGE_GARHWALI = Language (#const KBTS_LANGUAGE_GARHWALI)++pattern LANGUAGE_GARO :: Language+pattern LANGUAGE_GARO = Language (#const KBTS_LANGUAGE_GARO)++pattern LANGUAGE_GARSHUNI :: Language+pattern LANGUAGE_GARSHUNI = Language (#const KBTS_LANGUAGE_GARSHUNI)++pattern LANGUAGE_GEBA_KAREN :: Language+pattern LANGUAGE_GEBA_KAREN = Language (#const KBTS_LANGUAGE_GEBA_KAREN)++pattern LANGUAGE_GEEZ :: Language+pattern LANGUAGE_GEEZ = Language (#const KBTS_LANGUAGE_GEEZ)++pattern LANGUAGE_GEORGIAN :: Language+pattern LANGUAGE_GEORGIAN = Language (#const KBTS_LANGUAGE_GEORGIAN)++pattern LANGUAGE_GEPO :: Language+pattern LANGUAGE_GEPO = Language (#const KBTS_LANGUAGE_GEPO)++pattern LANGUAGE_GERMAN :: Language+pattern LANGUAGE_GERMAN = Language (#const KBTS_LANGUAGE_GERMAN)++pattern LANGUAGE_GIKUYU :: Language+pattern LANGUAGE_GIKUYU = Language (#const KBTS_LANGUAGE_GIKUYU)++pattern LANGUAGE_GILAKI :: Language+pattern LANGUAGE_GILAKI = Language (#const KBTS_LANGUAGE_GILAKI)++pattern LANGUAGE_GILBERTESE :: Language+pattern LANGUAGE_GILBERTESE = Language (#const KBTS_LANGUAGE_GILBERTESE)++pattern LANGUAGE_GILYAK :: Language+pattern LANGUAGE_GILYAK = Language (#const KBTS_LANGUAGE_GILYAK)++pattern LANGUAGE_GITHABUL :: Language+pattern LANGUAGE_GITHABUL = Language (#const KBTS_LANGUAGE_GITHABUL)++pattern LANGUAGE_GOGO :: Language+pattern LANGUAGE_GOGO = Language (#const KBTS_LANGUAGE_GOGO)++pattern LANGUAGE_GONDI :: Language+pattern LANGUAGE_GONDI = Language (#const KBTS_LANGUAGE_GONDI)++pattern LANGUAGE_GREEK :: Language+pattern LANGUAGE_GREEK = Language (#const KBTS_LANGUAGE_GREEK)++pattern LANGUAGE_GREENLANDIC :: Language+pattern LANGUAGE_GREENLANDIC = Language (#const KBTS_LANGUAGE_GREENLANDIC)++pattern LANGUAGE_GUARANI :: Language+pattern LANGUAGE_GUARANI = Language (#const KBTS_LANGUAGE_GUARANI)++pattern LANGUAGE_GUINEA :: Language+pattern LANGUAGE_GUINEA = Language (#const KBTS_LANGUAGE_GUINEA)++pattern LANGUAGE_GUJARATI :: Language+pattern LANGUAGE_GUJARATI = Language (#const KBTS_LANGUAGE_GUJARATI)++pattern LANGUAGE_GUMATJ :: Language+pattern LANGUAGE_GUMATJ = Language (#const KBTS_LANGUAGE_GUMATJ)++pattern LANGUAGE_GUMUZ :: Language+pattern LANGUAGE_GUMUZ = Language (#const KBTS_LANGUAGE_GUMUZ)++pattern LANGUAGE_GUPAPUYNGU :: Language+pattern LANGUAGE_GUPAPUYNGU = Language (#const KBTS_LANGUAGE_GUPAPUYNGU)++pattern LANGUAGE_GUSII :: Language+pattern LANGUAGE_GUSII = Language (#const KBTS_LANGUAGE_GUSII)++pattern LANGUAGE_HAIDA :: Language+pattern LANGUAGE_HAIDA = Language (#const KBTS_LANGUAGE_HAIDA)++pattern LANGUAGE_HAITIAN_CREOLE :: Language+pattern LANGUAGE_HAITIAN_CREOLE = Language (#const KBTS_LANGUAGE_HAITIAN_CREOLE)++pattern LANGUAGE_HALKOMELEM :: Language+pattern LANGUAGE_HALKOMELEM = Language (#const KBTS_LANGUAGE_HALKOMELEM)++pattern LANGUAGE_HAMMER_BANNA :: Language+pattern LANGUAGE_HAMMER_BANNA = Language (#const KBTS_LANGUAGE_HAMMER_BANNA)++pattern LANGUAGE_HARARI :: Language+pattern LANGUAGE_HARARI = Language (#const KBTS_LANGUAGE_HARARI)++pattern LANGUAGE_HARAUTI :: Language+pattern LANGUAGE_HARAUTI = Language (#const KBTS_LANGUAGE_HARAUTI)++pattern LANGUAGE_HARYANVI :: Language+pattern LANGUAGE_HARYANVI = Language (#const KBTS_LANGUAGE_HARYANVI)++pattern LANGUAGE_HAUSA :: Language+pattern LANGUAGE_HAUSA = Language (#const KBTS_LANGUAGE_HAUSA)++pattern LANGUAGE_HAVASUPAI_WALAPAI_YAVAPAI :: Language+pattern LANGUAGE_HAVASUPAI_WALAPAI_YAVAPAI = Language (#const KBTS_LANGUAGE_HAVASUPAI_WALAPAI_YAVAPAI)++pattern LANGUAGE_HAWAIIAN :: Language+pattern LANGUAGE_HAWAIIAN = Language (#const KBTS_LANGUAGE_HAWAIIAN)++pattern LANGUAGE_HAYA :: Language+pattern LANGUAGE_HAYA = Language (#const KBTS_LANGUAGE_HAYA)++pattern LANGUAGE_HAZARAGI :: Language+pattern LANGUAGE_HAZARAGI = Language (#const KBTS_LANGUAGE_HAZARAGI)++pattern LANGUAGE_HEBREW :: Language+pattern LANGUAGE_HEBREW = Language (#const KBTS_LANGUAGE_HEBREW)++pattern LANGUAGE_HEILTSUK :: Language+pattern LANGUAGE_HEILTSUK = Language (#const KBTS_LANGUAGE_HEILTSUK)++pattern LANGUAGE_HERERO :: Language+pattern LANGUAGE_HERERO = Language (#const KBTS_LANGUAGE_HERERO)++pattern LANGUAGE_HIGH_MARI :: Language+pattern LANGUAGE_HIGH_MARI = Language (#const KBTS_LANGUAGE_HIGH_MARI)++pattern LANGUAGE_HILIGAYNON :: Language+pattern LANGUAGE_HILIGAYNON = Language (#const KBTS_LANGUAGE_HILIGAYNON)++pattern LANGUAGE_HINDI :: Language+pattern LANGUAGE_HINDI = Language (#const KBTS_LANGUAGE_HINDI)++pattern LANGUAGE_HINDKO :: Language+pattern LANGUAGE_HINDKO = Language (#const KBTS_LANGUAGE_HINDKO)++pattern LANGUAGE_HIRI_MOTU :: Language+pattern LANGUAGE_HIRI_MOTU = Language (#const KBTS_LANGUAGE_HIRI_MOTU)++pattern LANGUAGE_HMONG :: Language+pattern LANGUAGE_HMONG = Language (#const KBTS_LANGUAGE_HMONG)++pattern LANGUAGE_HMONG_DAW :: Language+pattern LANGUAGE_HMONG_DAW = Language (#const KBTS_LANGUAGE_HMONG_DAW)++pattern LANGUAGE_HMONG_SHUAT :: Language+pattern LANGUAGE_HMONG_SHUAT = Language (#const KBTS_LANGUAGE_HMONG_SHUAT)++pattern LANGUAGE_HO :: Language+pattern LANGUAGE_HO = Language (#const KBTS_LANGUAGE_HO)++pattern LANGUAGE_HUNGARIAN :: Language+pattern LANGUAGE_HUNGARIAN = Language (#const KBTS_LANGUAGE_HUNGARIAN)++pattern LANGUAGE_IBAN :: Language+pattern LANGUAGE_IBAN = Language (#const KBTS_LANGUAGE_IBAN)++pattern LANGUAGE_IBIBIO :: Language+pattern LANGUAGE_IBIBIO = Language (#const KBTS_LANGUAGE_IBIBIO)++pattern LANGUAGE_ICELANDIC :: Language+pattern LANGUAGE_ICELANDIC = Language (#const KBTS_LANGUAGE_ICELANDIC)++pattern LANGUAGE_IDO :: Language+pattern LANGUAGE_IDO = Language (#const KBTS_LANGUAGE_IDO)++pattern LANGUAGE_IGBO :: Language+pattern LANGUAGE_IGBO = Language (#const KBTS_LANGUAGE_IGBO)++pattern LANGUAGE_IJO :: Language+pattern LANGUAGE_IJO = Language (#const KBTS_LANGUAGE_IJO)++pattern LANGUAGE_ILOKANO :: Language+pattern LANGUAGE_ILOKANO = Language (#const KBTS_LANGUAGE_ILOKANO)++pattern LANGUAGE_INARI_SAMI :: Language+pattern LANGUAGE_INARI_SAMI = Language (#const KBTS_LANGUAGE_INARI_SAMI)++pattern LANGUAGE_INDONESIAN :: Language+pattern LANGUAGE_INDONESIAN = Language (#const KBTS_LANGUAGE_INDONESIAN)++pattern LANGUAGE_INGUSH :: Language+pattern LANGUAGE_INGUSH = Language (#const KBTS_LANGUAGE_INGUSH)++pattern LANGUAGE_INTERLINGUA :: Language+pattern LANGUAGE_INTERLINGUA = Language (#const KBTS_LANGUAGE_INTERLINGUA)++pattern LANGUAGE_INTERLINGUE :: Language+pattern LANGUAGE_INTERLINGUE = Language (#const KBTS_LANGUAGE_INTERLINGUE)++pattern LANGUAGE_INUKTITUT :: Language+pattern LANGUAGE_INUKTITUT = Language (#const KBTS_LANGUAGE_INUKTITUT)++pattern LANGUAGE_INUPIAT :: Language+pattern LANGUAGE_INUPIAT = Language (#const KBTS_LANGUAGE_INUPIAT)++pattern LANGUAGE_IPA_PHONETIC :: Language+pattern LANGUAGE_IPA_PHONETIC = Language (#const KBTS_LANGUAGE_IPA_PHONETIC)++pattern LANGUAGE_IRISH :: Language+pattern LANGUAGE_IRISH = Language (#const KBTS_LANGUAGE_IRISH)++pattern LANGUAGE_IRISH_TRADITIONAL :: Language+pattern LANGUAGE_IRISH_TRADITIONAL = Language (#const KBTS_LANGUAGE_IRISH_TRADITIONAL)++pattern LANGUAGE_IRULA :: Language+pattern LANGUAGE_IRULA = Language (#const KBTS_LANGUAGE_IRULA)++pattern LANGUAGE_ITALIAN :: Language+pattern LANGUAGE_ITALIAN = Language (#const KBTS_LANGUAGE_ITALIAN)++pattern LANGUAGE_JAMAICAN_CREOLE :: Language+pattern LANGUAGE_JAMAICAN_CREOLE = Language (#const KBTS_LANGUAGE_JAMAICAN_CREOLE)++pattern LANGUAGE_JAPANESE :: Language+pattern LANGUAGE_JAPANESE = Language (#const KBTS_LANGUAGE_JAPANESE)++pattern LANGUAGE_JAVANESE :: Language+pattern LANGUAGE_JAVANESE = Language (#const KBTS_LANGUAGE_JAVANESE)++pattern LANGUAGE_JENNU_KURUMA :: Language+pattern LANGUAGE_JENNU_KURUMA = Language (#const KBTS_LANGUAGE_JENNU_KURUMA)++pattern LANGUAGE_JUDEO_TAT :: Language+pattern LANGUAGE_JUDEO_TAT = Language (#const KBTS_LANGUAGE_JUDEO_TAT)++pattern LANGUAGE_JULA :: Language+pattern LANGUAGE_JULA = Language (#const KBTS_LANGUAGE_JULA)++pattern LANGUAGE_KABARDIAN :: Language+pattern LANGUAGE_KABARDIAN = Language (#const KBTS_LANGUAGE_KABARDIAN)++pattern LANGUAGE_KABYLE :: Language+pattern LANGUAGE_KABYLE = Language (#const KBTS_LANGUAGE_KABYLE)++pattern LANGUAGE_KACHCHI :: Language+pattern LANGUAGE_KACHCHI = Language (#const KBTS_LANGUAGE_KACHCHI)++pattern LANGUAGE_KADIWEU :: Language+pattern LANGUAGE_KADIWEU = Language (#const KBTS_LANGUAGE_KADIWEU)++pattern LANGUAGE_KALENJIN :: Language+pattern LANGUAGE_KALENJIN = Language (#const KBTS_LANGUAGE_KALENJIN)++pattern LANGUAGE_KALMYK :: Language+pattern LANGUAGE_KALMYK = Language (#const KBTS_LANGUAGE_KALMYK)++pattern LANGUAGE_KAMBA :: Language+pattern LANGUAGE_KAMBA = Language (#const KBTS_LANGUAGE_KAMBA)++pattern LANGUAGE_KANAUJI :: Language+pattern LANGUAGE_KANAUJI = Language (#const KBTS_LANGUAGE_KANAUJI)++pattern LANGUAGE_KANNADA :: Language+pattern LANGUAGE_KANNADA = Language (#const KBTS_LANGUAGE_KANNADA)++pattern LANGUAGE_KANURI :: Language+pattern LANGUAGE_KANURI = Language (#const KBTS_LANGUAGE_KANURI)++pattern LANGUAGE_KAQCHIKEL :: Language+pattern LANGUAGE_KAQCHIKEL = Language (#const KBTS_LANGUAGE_KAQCHIKEL)++pattern LANGUAGE_KARACHAY :: Language+pattern LANGUAGE_KARACHAY = Language (#const KBTS_LANGUAGE_KARACHAY)++pattern LANGUAGE_KARAIM :: Language+pattern LANGUAGE_KARAIM = Language (#const KBTS_LANGUAGE_KARAIM)++pattern LANGUAGE_KARAKALPAK :: Language+pattern LANGUAGE_KARAKALPAK = Language (#const KBTS_LANGUAGE_KARAKALPAK)++pattern LANGUAGE_KARELIAN :: Language+pattern LANGUAGE_KARELIAN = Language (#const KBTS_LANGUAGE_KARELIAN)++pattern LANGUAGE_KAREN :: Language+pattern LANGUAGE_KAREN = Language (#const KBTS_LANGUAGE_KAREN)++pattern LANGUAGE_KASHMIRI :: Language+pattern LANGUAGE_KASHMIRI = Language (#const KBTS_LANGUAGE_KASHMIRI)++pattern LANGUAGE_KASHUBIAN :: Language+pattern LANGUAGE_KASHUBIAN = Language (#const KBTS_LANGUAGE_KASHUBIAN)++pattern LANGUAGE_KATE :: Language+pattern LANGUAGE_KATE = Language (#const KBTS_LANGUAGE_KATE)++pattern LANGUAGE_KAZAKH :: Language+pattern LANGUAGE_KAZAKH = Language (#const KBTS_LANGUAGE_KAZAKH)++pattern LANGUAGE_KEBENA :: Language+pattern LANGUAGE_KEBENA = Language (#const KBTS_LANGUAGE_KEBENA)++pattern LANGUAGE_KEKCHI :: Language+pattern LANGUAGE_KEKCHI = Language (#const KBTS_LANGUAGE_KEKCHI)++pattern LANGUAGE_KHAKASS :: Language+pattern LANGUAGE_KHAKASS = Language (#const KBTS_LANGUAGE_KHAKASS)++pattern LANGUAGE_KHAMTI_SHAN :: Language+pattern LANGUAGE_KHAMTI_SHAN = Language (#const KBTS_LANGUAGE_KHAMTI_SHAN)++pattern LANGUAGE_KHAMYANG :: Language+pattern LANGUAGE_KHAMYANG = Language (#const KBTS_LANGUAGE_KHAMYANG)++pattern LANGUAGE_KHANTY_KAZIM :: Language+pattern LANGUAGE_KHANTY_KAZIM = Language (#const KBTS_LANGUAGE_KHANTY_KAZIM)++pattern LANGUAGE_KHANTY_SHURISHKAR :: Language+pattern LANGUAGE_KHANTY_SHURISHKAR = Language (#const KBTS_LANGUAGE_KHANTY_SHURISHKAR)++pattern LANGUAGE_KHANTY_VAKHI :: Language+pattern LANGUAGE_KHANTY_VAKHI = Language (#const KBTS_LANGUAGE_KHANTY_VAKHI)++pattern LANGUAGE_KHASI :: Language+pattern LANGUAGE_KHASI = Language (#const KBTS_LANGUAGE_KHASI)++pattern LANGUAGE_KHENGKHA :: Language+pattern LANGUAGE_KHENGKHA = Language (#const KBTS_LANGUAGE_KHENGKHA)++pattern LANGUAGE_KHINALUG :: Language+pattern LANGUAGE_KHINALUG = Language (#const KBTS_LANGUAGE_KHINALUG)++pattern LANGUAGE_KHMER :: Language+pattern LANGUAGE_KHMER = Language (#const KBTS_LANGUAGE_KHMER)++pattern LANGUAGE_KHORASANI_TURKIC :: Language+pattern LANGUAGE_KHORASANI_TURKIC = Language (#const KBTS_LANGUAGE_KHORASANI_TURKIC)++pattern LANGUAGE_KHOWAR :: Language+pattern LANGUAGE_KHOWAR = Language (#const KBTS_LANGUAGE_KHOWAR)++pattern LANGUAGE_KHUTSURI_GEORGIAN :: Language+pattern LANGUAGE_KHUTSURI_GEORGIAN = Language (#const KBTS_LANGUAGE_KHUTSURI_GEORGIAN)++pattern LANGUAGE_KICHE :: Language+pattern LANGUAGE_KICHE = Language (#const KBTS_LANGUAGE_KICHE)++pattern LANGUAGE_KIKONGO :: Language+pattern LANGUAGE_KIKONGO = Language (#const KBTS_LANGUAGE_KIKONGO)++pattern LANGUAGE_KILDIN_SAMI :: Language+pattern LANGUAGE_KILDIN_SAMI = Language (#const KBTS_LANGUAGE_KILDIN_SAMI)++pattern LANGUAGE_KINYARWANDA :: Language+pattern LANGUAGE_KINYARWANDA = Language (#const KBTS_LANGUAGE_KINYARWANDA)++pattern LANGUAGE_KIRMANJKI :: Language+pattern LANGUAGE_KIRMANJKI = Language (#const KBTS_LANGUAGE_KIRMANJKI)++pattern LANGUAGE_KISII :: Language+pattern LANGUAGE_KISII = Language (#const KBTS_LANGUAGE_KISII)++pattern LANGUAGE_KITUBA :: Language+pattern LANGUAGE_KITUBA = Language (#const KBTS_LANGUAGE_KITUBA)++pattern LANGUAGE_KODAGU :: Language+pattern LANGUAGE_KODAGU = Language (#const KBTS_LANGUAGE_KODAGU)++pattern LANGUAGE_KOKNI :: Language+pattern LANGUAGE_KOKNI = Language (#const KBTS_LANGUAGE_KOKNI)++pattern LANGUAGE_KOMI :: Language+pattern LANGUAGE_KOMI = Language (#const KBTS_LANGUAGE_KOMI)++pattern LANGUAGE_KOMI_PERMYAK :: Language+pattern LANGUAGE_KOMI_PERMYAK = Language (#const KBTS_LANGUAGE_KOMI_PERMYAK)++pattern LANGUAGE_KOMI_ZYRIAN :: Language+pattern LANGUAGE_KOMI_ZYRIAN = Language (#const KBTS_LANGUAGE_KOMI_ZYRIAN)++pattern LANGUAGE_KOMO :: Language+pattern LANGUAGE_KOMO = Language (#const KBTS_LANGUAGE_KOMO)++pattern LANGUAGE_KOMSO :: Language+pattern LANGUAGE_KOMSO = Language (#const KBTS_LANGUAGE_KOMSO)++pattern LANGUAGE_KONGO :: Language+pattern LANGUAGE_KONGO = Language (#const KBTS_LANGUAGE_KONGO)++pattern LANGUAGE_KONKANI :: Language+pattern LANGUAGE_KONKANI = Language (#const KBTS_LANGUAGE_KONKANI)++pattern LANGUAGE_KOORETE :: Language+pattern LANGUAGE_KOORETE = Language (#const KBTS_LANGUAGE_KOORETE)++pattern LANGUAGE_KOREAN :: Language+pattern LANGUAGE_KOREAN = Language (#const KBTS_LANGUAGE_KOREAN)++pattern LANGUAGE_KOREAO_OLD_HANGUL :: Language+pattern LANGUAGE_KOREAO_OLD_HANGUL = Language (#const KBTS_LANGUAGE_KOREAO_OLD_HANGUL)++pattern LANGUAGE_KORYAK :: Language+pattern LANGUAGE_KORYAK = Language (#const KBTS_LANGUAGE_KORYAK)++pattern LANGUAGE_KOSRAEAN :: Language+pattern LANGUAGE_KOSRAEAN = Language (#const KBTS_LANGUAGE_KOSRAEAN)++pattern LANGUAGE_KPELLE :: Language+pattern LANGUAGE_KPELLE = Language (#const KBTS_LANGUAGE_KPELLE)++pattern LANGUAGE_KPELLE_LIBERIA :: Language+pattern LANGUAGE_KPELLE_LIBERIA = Language (#const KBTS_LANGUAGE_KPELLE_LIBERIA)++pattern LANGUAGE_KRIO :: Language+pattern LANGUAGE_KRIO = Language (#const KBTS_LANGUAGE_KRIO)++pattern LANGUAGE_KRYMCHAK :: Language+pattern LANGUAGE_KRYMCHAK = Language (#const KBTS_LANGUAGE_KRYMCHAK)++pattern LANGUAGE_KUANYAMA :: Language+pattern LANGUAGE_KUANYAMA = Language (#const KBTS_LANGUAGE_KUANYAMA)++pattern LANGUAGE_KUBE :: Language+pattern LANGUAGE_KUBE = Language (#const KBTS_LANGUAGE_KUBE)++pattern LANGUAGE_KUI :: Language+pattern LANGUAGE_KUI = Language (#const KBTS_LANGUAGE_KUI)++pattern LANGUAGE_KULVI :: Language+pattern LANGUAGE_KULVI = Language (#const KBTS_LANGUAGE_KULVI)++pattern LANGUAGE_KUMAONI :: Language+pattern LANGUAGE_KUMAONI = Language (#const KBTS_LANGUAGE_KUMAONI)++pattern LANGUAGE_KUMYK :: Language+pattern LANGUAGE_KUMYK = Language (#const KBTS_LANGUAGE_KUMYK)++pattern LANGUAGE_KURDISH :: Language+pattern LANGUAGE_KURDISH = Language (#const KBTS_LANGUAGE_KURDISH)++pattern LANGUAGE_KURUKH :: Language+pattern LANGUAGE_KURUKH = Language (#const KBTS_LANGUAGE_KURUKH)++pattern LANGUAGE_KUY :: Language+pattern LANGUAGE_KUY = Language (#const KBTS_LANGUAGE_KUY)++pattern LANGUAGE_KWAKWALA :: Language+pattern LANGUAGE_KWAKWALA = Language (#const KBTS_LANGUAGE_KWAKWALA)++pattern LANGUAGE_KYRGYZ :: Language+pattern LANGUAGE_KYRGYZ = Language (#const KBTS_LANGUAGE_KYRGYZ)++pattern LANGUAGE_L_CREE :: Language+pattern LANGUAGE_L_CREE = Language (#const KBTS_LANGUAGE_L_CREE)++pattern LANGUAGE_LADAKHI :: Language+pattern LANGUAGE_LADAKHI = Language (#const KBTS_LANGUAGE_LADAKHI)++pattern LANGUAGE_LADIN :: Language+pattern LANGUAGE_LADIN = Language (#const KBTS_LANGUAGE_LADIN)++pattern LANGUAGE_LADINO :: Language+pattern LANGUAGE_LADINO = Language (#const KBTS_LANGUAGE_LADINO)++pattern LANGUAGE_LAHULI :: Language+pattern LANGUAGE_LAHULI = Language (#const KBTS_LANGUAGE_LAHULI)++pattern LANGUAGE_LAK :: Language+pattern LANGUAGE_LAK = Language (#const KBTS_LANGUAGE_LAK)++pattern LANGUAGE_LAKI :: Language+pattern LANGUAGE_LAKI = Language (#const KBTS_LANGUAGE_LAKI)++pattern LANGUAGE_LAMBANI :: Language+pattern LANGUAGE_LAMBANI = Language (#const KBTS_LANGUAGE_LAMBANI)++pattern LANGUAGE_LAMPUNG :: Language+pattern LANGUAGE_LAMPUNG = Language (#const KBTS_LANGUAGE_LAMPUNG)++pattern LANGUAGE_LAO :: Language+pattern LANGUAGE_LAO = Language (#const KBTS_LANGUAGE_LAO)++pattern LANGUAGE_LATIN :: Language+pattern LANGUAGE_LATIN = Language (#const KBTS_LANGUAGE_LATIN)++pattern LANGUAGE_LATVIAN :: Language+pattern LANGUAGE_LATVIAN = Language (#const KBTS_LANGUAGE_LATVIAN)++pattern LANGUAGE_LAZ :: Language+pattern LANGUAGE_LAZ = Language (#const KBTS_LANGUAGE_LAZ)++pattern LANGUAGE_LELEMI :: Language+pattern LANGUAGE_LELEMI = Language (#const KBTS_LANGUAGE_LELEMI)++pattern LANGUAGE_LEZGI :: Language+pattern LANGUAGE_LEZGI = Language (#const KBTS_LANGUAGE_LEZGI)++pattern LANGUAGE_LIGURIAN :: Language+pattern LANGUAGE_LIGURIAN = Language (#const KBTS_LANGUAGE_LIGURIAN)++pattern LANGUAGE_LIMBU :: Language+pattern LANGUAGE_LIMBU = Language (#const KBTS_LANGUAGE_LIMBU)++pattern LANGUAGE_LIMBURGISH :: Language+pattern LANGUAGE_LIMBURGISH = Language (#const KBTS_LANGUAGE_LIMBURGISH)++pattern LANGUAGE_LINGALA :: Language+pattern LANGUAGE_LINGALA = Language (#const KBTS_LANGUAGE_LINGALA)++pattern LANGUAGE_LIPO :: Language+pattern LANGUAGE_LIPO = Language (#const KBTS_LANGUAGE_LIPO)++pattern LANGUAGE_LISU :: Language+pattern LANGUAGE_LISU = Language (#const KBTS_LANGUAGE_LISU)++pattern LANGUAGE_LITHUANIAN :: Language+pattern LANGUAGE_LITHUANIAN = Language (#const KBTS_LANGUAGE_LITHUANIAN)++pattern LANGUAGE_LIV :: Language+pattern LANGUAGE_LIV = Language (#const KBTS_LANGUAGE_LIV)++pattern LANGUAGE_LOJBAN :: Language+pattern LANGUAGE_LOJBAN = Language (#const KBTS_LANGUAGE_LOJBAN)++pattern LANGUAGE_LOMA :: Language+pattern LANGUAGE_LOMA = Language (#const KBTS_LANGUAGE_LOMA)++pattern LANGUAGE_LOMBARD :: Language+pattern LANGUAGE_LOMBARD = Language (#const KBTS_LANGUAGE_LOMBARD)++pattern LANGUAGE_LOMWE :: Language+pattern LANGUAGE_LOMWE = Language (#const KBTS_LANGUAGE_LOMWE)++pattern LANGUAGE_LOW_MARI :: Language+pattern LANGUAGE_LOW_MARI = Language (#const KBTS_LANGUAGE_LOW_MARI)++pattern LANGUAGE_LOW_SAXON :: Language+pattern LANGUAGE_LOW_SAXON = Language (#const KBTS_LANGUAGE_LOW_SAXON)++pattern LANGUAGE_LOWER_SORBIAN :: Language+pattern LANGUAGE_LOWER_SORBIAN = Language (#const KBTS_LANGUAGE_LOWER_SORBIAN)++pattern LANGUAGE_LU :: Language+pattern LANGUAGE_LU = Language (#const KBTS_LANGUAGE_LU)++pattern LANGUAGE_LUBA_KATANGA :: Language+pattern LANGUAGE_LUBA_KATANGA = Language (#const KBTS_LANGUAGE_LUBA_KATANGA)++pattern LANGUAGE_LUBA_LULUA :: Language+pattern LANGUAGE_LUBA_LULUA = Language (#const KBTS_LANGUAGE_LUBA_LULUA)++pattern LANGUAGE_LULE_SAMI :: Language+pattern LANGUAGE_LULE_SAMI = Language (#const KBTS_LANGUAGE_LULE_SAMI)++pattern LANGUAGE_LUO :: Language+pattern LANGUAGE_LUO = Language (#const KBTS_LANGUAGE_LUO)++pattern LANGUAGE_LURI :: Language+pattern LANGUAGE_LURI = Language (#const KBTS_LANGUAGE_LURI)++pattern LANGUAGE_LUSHOOTSEED :: Language+pattern LANGUAGE_LUSHOOTSEED = Language (#const KBTS_LANGUAGE_LUSHOOTSEED)++pattern LANGUAGE_LUXEMBOURGISH :: Language+pattern LANGUAGE_LUXEMBOURGISH = Language (#const KBTS_LANGUAGE_LUXEMBOURGISH)++pattern LANGUAGE_LUYIA :: Language+pattern LANGUAGE_LUYIA = Language (#const KBTS_LANGUAGE_LUYIA)++pattern LANGUAGE_MACEDONIAN :: Language+pattern LANGUAGE_MACEDONIAN = Language (#const KBTS_LANGUAGE_MACEDONIAN)++pattern LANGUAGE_MADURA :: Language+pattern LANGUAGE_MADURA = Language (#const KBTS_LANGUAGE_MADURA)++pattern LANGUAGE_MAGAHI :: Language+pattern LANGUAGE_MAGAHI = Language (#const KBTS_LANGUAGE_MAGAHI)++pattern LANGUAGE_MAITHILI :: Language+pattern LANGUAGE_MAITHILI = Language (#const KBTS_LANGUAGE_MAITHILI)++pattern LANGUAGE_MAJANG :: Language+pattern LANGUAGE_MAJANG = Language (#const KBTS_LANGUAGE_MAJANG)++pattern LANGUAGE_MAKASAR :: Language+pattern LANGUAGE_MAKASAR = Language (#const KBTS_LANGUAGE_MAKASAR)++pattern LANGUAGE_MAKHUWA :: Language+pattern LANGUAGE_MAKHUWA = Language (#const KBTS_LANGUAGE_MAKHUWA)++pattern LANGUAGE_MAKONDE :: Language+pattern LANGUAGE_MAKONDE = Language (#const KBTS_LANGUAGE_MAKONDE)++pattern LANGUAGE_MALAGASY :: Language+pattern LANGUAGE_MALAGASY = Language (#const KBTS_LANGUAGE_MALAGASY)++pattern LANGUAGE_MALAY :: Language+pattern LANGUAGE_MALAY = Language (#const KBTS_LANGUAGE_MALAY)++pattern LANGUAGE_MALAYALAM :: Language+pattern LANGUAGE_MALAYALAM = Language (#const KBTS_LANGUAGE_MALAYALAM)++pattern LANGUAGE_MALAYALAM_REFORMED :: Language+pattern LANGUAGE_MALAYALAM_REFORMED = Language (#const KBTS_LANGUAGE_MALAYALAM_REFORMED)++pattern LANGUAGE_MALE :: Language+pattern LANGUAGE_MALE = Language (#const KBTS_LANGUAGE_MALE)++pattern LANGUAGE_MALINKE :: Language+pattern LANGUAGE_MALINKE = Language (#const KBTS_LANGUAGE_MALINKE)++pattern LANGUAGE_MALTESE :: Language+pattern LANGUAGE_MALTESE = Language (#const KBTS_LANGUAGE_MALTESE)++pattern LANGUAGE_MAM :: Language+pattern LANGUAGE_MAM = Language (#const KBTS_LANGUAGE_MAM)++pattern LANGUAGE_MANCHU :: Language+pattern LANGUAGE_MANCHU = Language (#const KBTS_LANGUAGE_MANCHU)++pattern LANGUAGE_MANDAR :: Language+pattern LANGUAGE_MANDAR = Language (#const KBTS_LANGUAGE_MANDAR)++pattern LANGUAGE_MANDINKA :: Language+pattern LANGUAGE_MANDINKA = Language (#const KBTS_LANGUAGE_MANDINKA)++pattern LANGUAGE_MANINKA :: Language+pattern LANGUAGE_MANINKA = Language (#const KBTS_LANGUAGE_MANINKA)++pattern LANGUAGE_MANIPURI :: Language+pattern LANGUAGE_MANIPURI = Language (#const KBTS_LANGUAGE_MANIPURI)++pattern LANGUAGE_MANO :: Language+pattern LANGUAGE_MANO = Language (#const KBTS_LANGUAGE_MANO)++pattern LANGUAGE_MANSI :: Language+pattern LANGUAGE_MANSI = Language (#const KBTS_LANGUAGE_MANSI)++pattern LANGUAGE_MANX :: Language+pattern LANGUAGE_MANX = Language (#const KBTS_LANGUAGE_MANX)++pattern LANGUAGE_MAORI :: Language+pattern LANGUAGE_MAORI = Language (#const KBTS_LANGUAGE_MAORI)++pattern LANGUAGE_MAPUDUNGUN :: Language+pattern LANGUAGE_MAPUDUNGUN = Language (#const KBTS_LANGUAGE_MAPUDUNGUN)++pattern LANGUAGE_MARATHI :: Language+pattern LANGUAGE_MARATHI = Language (#const KBTS_LANGUAGE_MARATHI)++pattern LANGUAGE_MARSHALLESE :: Language+pattern LANGUAGE_MARSHALLESE = Language (#const KBTS_LANGUAGE_MARSHALLESE)++pattern LANGUAGE_MARWARI :: Language+pattern LANGUAGE_MARWARI = Language (#const KBTS_LANGUAGE_MARWARI)++pattern LANGUAGE_MAYAN :: Language+pattern LANGUAGE_MAYAN = Language (#const KBTS_LANGUAGE_MAYAN)++pattern LANGUAGE_MAZANDERANI :: Language+pattern LANGUAGE_MAZANDERANI = Language (#const KBTS_LANGUAGE_MAZANDERANI)++pattern LANGUAGE_MBEMBE_TIGON :: Language+pattern LANGUAGE_MBEMBE_TIGON = Language (#const KBTS_LANGUAGE_MBEMBE_TIGON)++pattern LANGUAGE_MBO :: Language+pattern LANGUAGE_MBO = Language (#const KBTS_LANGUAGE_MBO)++pattern LANGUAGE_MBUNDU :: Language+pattern LANGUAGE_MBUNDU = Language (#const KBTS_LANGUAGE_MBUNDU)++pattern LANGUAGE_MEDUMBA :: Language+pattern LANGUAGE_MEDUMBA = Language (#const KBTS_LANGUAGE_MEDUMBA)++pattern LANGUAGE_MEEN :: Language+pattern LANGUAGE_MEEN = Language (#const KBTS_LANGUAGE_MEEN)++pattern LANGUAGE_MENDE :: Language+pattern LANGUAGE_MENDE = Language (#const KBTS_LANGUAGE_MENDE)++pattern LANGUAGE_MERU :: Language+pattern LANGUAGE_MERU = Language (#const KBTS_LANGUAGE_MERU)++pattern LANGUAGE_MEWATI :: Language+pattern LANGUAGE_MEWATI = Language (#const KBTS_LANGUAGE_MEWATI)++pattern LANGUAGE_MINANGKABAU :: Language+pattern LANGUAGE_MINANGKABAU = Language (#const KBTS_LANGUAGE_MINANGKABAU)++pattern LANGUAGE_MINJANGBAL :: Language+pattern LANGUAGE_MINJANGBAL = Language (#const KBTS_LANGUAGE_MINJANGBAL)++pattern LANGUAGE_MIRANDESE :: Language+pattern LANGUAGE_MIRANDESE = Language (#const KBTS_LANGUAGE_MIRANDESE)++pattern LANGUAGE_MIZO :: Language+pattern LANGUAGE_MIZO = Language (#const KBTS_LANGUAGE_MIZO)++pattern LANGUAGE_MOHAWK :: Language+pattern LANGUAGE_MOHAWK = Language (#const KBTS_LANGUAGE_MOHAWK)++pattern LANGUAGE_MOKSHA :: Language+pattern LANGUAGE_MOKSHA = Language (#const KBTS_LANGUAGE_MOKSHA)++pattern LANGUAGE_MOLDAVIAN :: Language+pattern LANGUAGE_MOLDAVIAN = Language (#const KBTS_LANGUAGE_MOLDAVIAN)++pattern LANGUAGE_MON :: Language+pattern LANGUAGE_MON = Language (#const KBTS_LANGUAGE_MON)++pattern LANGUAGE_MONGOLIAN :: Language+pattern LANGUAGE_MONGOLIAN = Language (#const KBTS_LANGUAGE_MONGOLIAN)++pattern LANGUAGE_MOOSE_CREE :: Language+pattern LANGUAGE_MOOSE_CREE = Language (#const KBTS_LANGUAGE_MOOSE_CREE)++pattern LANGUAGE_MORISYEN :: Language+pattern LANGUAGE_MORISYEN = Language (#const KBTS_LANGUAGE_MORISYEN)++pattern LANGUAGE_MOROCCAN :: Language+pattern LANGUAGE_MOROCCAN = Language (#const KBTS_LANGUAGE_MOROCCAN)++pattern LANGUAGE_MOSSI :: Language+pattern LANGUAGE_MOSSI = Language (#const KBTS_LANGUAGE_MOSSI)++pattern LANGUAGE_MUNDARI :: Language+pattern LANGUAGE_MUNDARI = Language (#const KBTS_LANGUAGE_MUNDARI)++pattern LANGUAGE_MUSCOGEE :: Language+pattern LANGUAGE_MUSCOGEE = Language (#const KBTS_LANGUAGE_MUSCOGEE)++pattern LANGUAGE_N_CREE :: Language+pattern LANGUAGE_N_CREE = Language (#const KBTS_LANGUAGE_N_CREE)++pattern LANGUAGE_NAGA_ASSAMESE :: Language+pattern LANGUAGE_NAGA_ASSAMESE = Language (#const KBTS_LANGUAGE_NAGA_ASSAMESE)++pattern LANGUAGE_NAGARI :: Language+pattern LANGUAGE_NAGARI = Language (#const KBTS_LANGUAGE_NAGARI)++pattern LANGUAGE_NAHUATL :: Language+pattern LANGUAGE_NAHUATL = Language (#const KBTS_LANGUAGE_NAHUATL)++pattern LANGUAGE_NANAI :: Language+pattern LANGUAGE_NANAI = Language (#const KBTS_LANGUAGE_NANAI)++pattern LANGUAGE_NASKAPI :: Language+pattern LANGUAGE_NASKAPI = Language (#const KBTS_LANGUAGE_NASKAPI)++pattern LANGUAGE_NAURUAN :: Language+pattern LANGUAGE_NAURUAN = Language (#const KBTS_LANGUAGE_NAURUAN)++pattern LANGUAGE_NAVAJO :: Language+pattern LANGUAGE_NAVAJO = Language (#const KBTS_LANGUAGE_NAVAJO)++pattern LANGUAGE_NDAU :: Language+pattern LANGUAGE_NDAU = Language (#const KBTS_LANGUAGE_NDAU)++pattern LANGUAGE_NDEBELE :: Language+pattern LANGUAGE_NDEBELE = Language (#const KBTS_LANGUAGE_NDEBELE)++pattern LANGUAGE_NDONGA :: Language+pattern LANGUAGE_NDONGA = Language (#const KBTS_LANGUAGE_NDONGA)++pattern LANGUAGE_NEAPOLITAN :: Language+pattern LANGUAGE_NEAPOLITAN = Language (#const KBTS_LANGUAGE_NEAPOLITAN)++pattern LANGUAGE_NEPALI :: Language+pattern LANGUAGE_NEPALI = Language (#const KBTS_LANGUAGE_NEPALI)++pattern LANGUAGE_NEWARI :: Language+pattern LANGUAGE_NEWARI = Language (#const KBTS_LANGUAGE_NEWARI)++pattern LANGUAGE_NGBAKA :: Language+pattern LANGUAGE_NGBAKA = Language (#const KBTS_LANGUAGE_NGBAKA)++pattern LANGUAGE_NIGERIAN_FULFULDE :: Language+pattern LANGUAGE_NIGERIAN_FULFULDE = Language (#const KBTS_LANGUAGE_NIGERIAN_FULFULDE)++pattern LANGUAGE_NIMADI :: Language+pattern LANGUAGE_NIMADI = Language (#const KBTS_LANGUAGE_NIMADI)++pattern LANGUAGE_NISI :: Language+pattern LANGUAGE_NISI = Language (#const KBTS_LANGUAGE_NISI)++pattern LANGUAGE_NIUEAN :: Language+pattern LANGUAGE_NIUEAN = Language (#const KBTS_LANGUAGE_NIUEAN)++pattern LANGUAGE_NKO :: Language+pattern LANGUAGE_NKO = Language (#const KBTS_LANGUAGE_NKO)++pattern LANGUAGE_NOGAI :: Language+pattern LANGUAGE_NOGAI = Language (#const KBTS_LANGUAGE_NOGAI)++pattern LANGUAGE_NORFOLK :: Language+pattern LANGUAGE_NORFOLK = Language (#const KBTS_LANGUAGE_NORFOLK)++pattern LANGUAGE_NORTH_SLAVEY :: Language+pattern LANGUAGE_NORTH_SLAVEY = Language (#const KBTS_LANGUAGE_NORTH_SLAVEY)++pattern LANGUAGE_NORTHERN_EMBERA :: Language+pattern LANGUAGE_NORTHERN_EMBERA = Language (#const KBTS_LANGUAGE_NORTHERN_EMBERA)++pattern LANGUAGE_NORTHERN_SAMI :: Language+pattern LANGUAGE_NORTHERN_SAMI = Language (#const KBTS_LANGUAGE_NORTHERN_SAMI)++pattern LANGUAGE_NORTHERN_SOTHO :: Language+pattern LANGUAGE_NORTHERN_SOTHO = Language (#const KBTS_LANGUAGE_NORTHERN_SOTHO)++pattern LANGUAGE_NORTHERN_TAI :: Language+pattern LANGUAGE_NORTHERN_TAI = Language (#const KBTS_LANGUAGE_NORTHERN_TAI)++pattern LANGUAGE_NORWAY_HOUSE_CREE :: Language+pattern LANGUAGE_NORWAY_HOUSE_CREE = Language (#const KBTS_LANGUAGE_NORWAY_HOUSE_CREE)++pattern LANGUAGE_NORWEGIAN :: Language+pattern LANGUAGE_NORWEGIAN = Language (#const KBTS_LANGUAGE_NORWEGIAN)++pattern LANGUAGE_NORWEGIAN_NYNORSK :: Language+pattern LANGUAGE_NORWEGIAN_NYNORSK = Language (#const KBTS_LANGUAGE_NORWEGIAN_NYNORSK)++pattern LANGUAGE_NOVIAL :: Language+pattern LANGUAGE_NOVIAL = Language (#const KBTS_LANGUAGE_NOVIAL)++pattern LANGUAGE_NUMANGGANG :: Language+pattern LANGUAGE_NUMANGGANG = Language (#const KBTS_LANGUAGE_NUMANGGANG)++pattern LANGUAGE_NUNAVIK_INUKTITUT :: Language+pattern LANGUAGE_NUNAVIK_INUKTITUT = Language (#const KBTS_LANGUAGE_NUNAVIK_INUKTITUT)++pattern LANGUAGE_NUU_CHAH_NULTH :: Language+pattern LANGUAGE_NUU_CHAH_NULTH = Language (#const KBTS_LANGUAGE_NUU_CHAH_NULTH)++pattern LANGUAGE_NYAMWEZI :: Language+pattern LANGUAGE_NYAMWEZI = Language (#const KBTS_LANGUAGE_NYAMWEZI)++pattern LANGUAGE_NYANKOLE :: Language+pattern LANGUAGE_NYANKOLE = Language (#const KBTS_LANGUAGE_NYANKOLE)++pattern LANGUAGE_OCCITAN :: Language+pattern LANGUAGE_OCCITAN = Language (#const KBTS_LANGUAGE_OCCITAN)++pattern LANGUAGE_ODIA :: Language+pattern LANGUAGE_ODIA = Language (#const KBTS_LANGUAGE_ODIA)++pattern LANGUAGE_OJI_CREE :: Language+pattern LANGUAGE_OJI_CREE = Language (#const KBTS_LANGUAGE_OJI_CREE)++pattern LANGUAGE_OJIBWAY :: Language+pattern LANGUAGE_OJIBWAY = Language (#const KBTS_LANGUAGE_OJIBWAY)++pattern LANGUAGE_OLD_IRISH :: Language+pattern LANGUAGE_OLD_IRISH = Language (#const KBTS_LANGUAGE_OLD_IRISH)++pattern LANGUAGE_OLD_JAVANESE :: Language+pattern LANGUAGE_OLD_JAVANESE = Language (#const KBTS_LANGUAGE_OLD_JAVANESE)++pattern LANGUAGE_ONEIDA :: Language+pattern LANGUAGE_ONEIDA = Language (#const KBTS_LANGUAGE_ONEIDA)++pattern LANGUAGE_ONONDAGA :: Language+pattern LANGUAGE_ONONDAGA = Language (#const KBTS_LANGUAGE_ONONDAGA)++pattern LANGUAGE_OROMO :: Language+pattern LANGUAGE_OROMO = Language (#const KBTS_LANGUAGE_OROMO)++pattern LANGUAGE_OSSETIAN :: Language+pattern LANGUAGE_OSSETIAN = Language (#const KBTS_LANGUAGE_OSSETIAN)++pattern LANGUAGE_PA_O_KAREN :: Language+pattern LANGUAGE_PA_O_KAREN = Language (#const KBTS_LANGUAGE_PA_O_KAREN)++pattern LANGUAGE_PALAUAN :: Language+pattern LANGUAGE_PALAUAN = Language (#const KBTS_LANGUAGE_PALAUAN)++pattern LANGUAGE_PALAUNG :: Language+pattern LANGUAGE_PALAUNG = Language (#const KBTS_LANGUAGE_PALAUNG)++pattern LANGUAGE_PALESTINIAN_ARAMAIC :: Language+pattern LANGUAGE_PALESTINIAN_ARAMAIC = Language (#const KBTS_LANGUAGE_PALESTINIAN_ARAMAIC)++pattern LANGUAGE_PALI :: Language+pattern LANGUAGE_PALI = Language (#const KBTS_LANGUAGE_PALI)++pattern LANGUAGE_PALPA :: Language+pattern LANGUAGE_PALPA = Language (#const KBTS_LANGUAGE_PALPA)++pattern LANGUAGE_PAMPANGAN :: Language+pattern LANGUAGE_PAMPANGAN = Language (#const KBTS_LANGUAGE_PAMPANGAN)++pattern LANGUAGE_PANGASINAN :: Language+pattern LANGUAGE_PANGASINAN = Language (#const KBTS_LANGUAGE_PANGASINAN)++pattern LANGUAGE_PAPIAMENTU :: Language+pattern LANGUAGE_PAPIAMENTU = Language (#const KBTS_LANGUAGE_PAPIAMENTU)++pattern LANGUAGE_PASHTO :: Language+pattern LANGUAGE_PASHTO = Language (#const KBTS_LANGUAGE_PASHTO)++pattern LANGUAGE_PATTANI_MALAY :: Language+pattern LANGUAGE_PATTANI_MALAY = Language (#const KBTS_LANGUAGE_PATTANI_MALAY)++pattern LANGUAGE_PENNSYLVANIA_GERMAN :: Language+pattern LANGUAGE_PENNSYLVANIA_GERMAN = Language (#const KBTS_LANGUAGE_PENNSYLVANIA_GERMAN)++pattern LANGUAGE_PERSIAN :: Language+pattern LANGUAGE_PERSIAN = Language (#const KBTS_LANGUAGE_PERSIAN)++pattern LANGUAGE_PHAKE :: Language+pattern LANGUAGE_PHAKE = Language (#const KBTS_LANGUAGE_PHAKE)++pattern LANGUAGE_PICARD :: Language+pattern LANGUAGE_PICARD = Language (#const KBTS_LANGUAGE_PICARD)++pattern LANGUAGE_PIEMONTESE :: Language+pattern LANGUAGE_PIEMONTESE = Language (#const KBTS_LANGUAGE_PIEMONTESE)++pattern LANGUAGE_PILAGA :: Language+pattern LANGUAGE_PILAGA = Language (#const KBTS_LANGUAGE_PILAGA)++pattern LANGUAGE_PITE_SAMI :: Language+pattern LANGUAGE_PITE_SAMI = Language (#const KBTS_LANGUAGE_PITE_SAMI)++pattern LANGUAGE_POCOMCHI :: Language+pattern LANGUAGE_POCOMCHI = Language (#const KBTS_LANGUAGE_POCOMCHI)++pattern LANGUAGE_POHNPEIAN :: Language+pattern LANGUAGE_POHNPEIAN = Language (#const KBTS_LANGUAGE_POHNPEIAN)++pattern LANGUAGE_POLISH :: Language+pattern LANGUAGE_POLISH = Language (#const KBTS_LANGUAGE_POLISH)++pattern LANGUAGE_POLYTONIC_GREEK :: Language+pattern LANGUAGE_POLYTONIC_GREEK = Language (#const KBTS_LANGUAGE_POLYTONIC_GREEK)++pattern LANGUAGE_PORTUGUESE :: Language+pattern LANGUAGE_PORTUGUESE = Language (#const KBTS_LANGUAGE_PORTUGUESE)++pattern LANGUAGE_PROVENCAL :: Language+pattern LANGUAGE_PROVENCAL = Language (#const KBTS_LANGUAGE_PROVENCAL)++pattern LANGUAGE_PUNJABI :: Language+pattern LANGUAGE_PUNJABI = Language (#const KBTS_LANGUAGE_PUNJABI)++pattern LANGUAGE_QUECHUA :: Language+pattern LANGUAGE_QUECHUA = Language (#const KBTS_LANGUAGE_QUECHUA)++pattern LANGUAGE_QUECHUA_BOLIVIA :: Language+pattern LANGUAGE_QUECHUA_BOLIVIA = Language (#const KBTS_LANGUAGE_QUECHUA_BOLIVIA)++pattern LANGUAGE_QUECHUA_ECUADOR :: Language+pattern LANGUAGE_QUECHUA_ECUADOR = Language (#const KBTS_LANGUAGE_QUECHUA_ECUADOR)++pattern LANGUAGE_QUECHUA_PERU :: Language+pattern LANGUAGE_QUECHUA_PERU = Language (#const KBTS_LANGUAGE_QUECHUA_PERU)++pattern LANGUAGE_R_CREE :: Language+pattern LANGUAGE_R_CREE = Language (#const KBTS_LANGUAGE_R_CREE)++pattern LANGUAGE_RAJASTHANI :: Language+pattern LANGUAGE_RAJASTHANI = Language (#const KBTS_LANGUAGE_RAJASTHANI)++pattern LANGUAGE_RAKHINE :: Language+pattern LANGUAGE_RAKHINE = Language (#const KBTS_LANGUAGE_RAKHINE)++pattern LANGUAGE_RAROTONGAN :: Language+pattern LANGUAGE_RAROTONGAN = Language (#const KBTS_LANGUAGE_RAROTONGAN)++pattern LANGUAGE_REJANG :: Language+pattern LANGUAGE_REJANG = Language (#const KBTS_LANGUAGE_REJANG)++pattern LANGUAGE_RIANG :: Language+pattern LANGUAGE_RIANG = Language (#const KBTS_LANGUAGE_RIANG)++pattern LANGUAGE_RIPUARIAN :: Language+pattern LANGUAGE_RIPUARIAN = Language (#const KBTS_LANGUAGE_RIPUARIAN)++pattern LANGUAGE_RITARUNGO :: Language+pattern LANGUAGE_RITARUNGO = Language (#const KBTS_LANGUAGE_RITARUNGO)++pattern LANGUAGE_ROHINGYA :: Language+pattern LANGUAGE_ROHINGYA = Language (#const KBTS_LANGUAGE_ROHINGYA)++pattern LANGUAGE_ROMANIAN :: Language+pattern LANGUAGE_ROMANIAN = Language (#const KBTS_LANGUAGE_ROMANIAN)++pattern LANGUAGE_ROMANSH :: Language+pattern LANGUAGE_ROMANSH = Language (#const KBTS_LANGUAGE_ROMANSH)++pattern LANGUAGE_ROMANY :: Language+pattern LANGUAGE_ROMANY = Language (#const KBTS_LANGUAGE_ROMANY)++pattern LANGUAGE_ROTUMAN :: Language+pattern LANGUAGE_ROTUMAN = Language (#const KBTS_LANGUAGE_ROTUMAN)++pattern LANGUAGE_RUNDI :: Language+pattern LANGUAGE_RUNDI = Language (#const KBTS_LANGUAGE_RUNDI)++pattern LANGUAGE_RUSSIAN :: Language+pattern LANGUAGE_RUSSIAN = Language (#const KBTS_LANGUAGE_RUSSIAN)++pattern LANGUAGE_RUSSIAN_BURIAT :: Language+pattern LANGUAGE_RUSSIAN_BURIAT = Language (#const KBTS_LANGUAGE_RUSSIAN_BURIAT)++pattern LANGUAGE_RUSYN :: Language+pattern LANGUAGE_RUSYN = Language (#const KBTS_LANGUAGE_RUSYN)++pattern LANGUAGE_SADRI :: Language+pattern LANGUAGE_SADRI = Language (#const KBTS_LANGUAGE_SADRI)++pattern LANGUAGE_SAKHA :: Language+pattern LANGUAGE_SAKHA = Language (#const KBTS_LANGUAGE_SAKHA)++pattern LANGUAGE_SAMOAN :: Language+pattern LANGUAGE_SAMOAN = Language (#const KBTS_LANGUAGE_SAMOAN)++pattern LANGUAGE_SAMOGITIAN :: Language+pattern LANGUAGE_SAMOGITIAN = Language (#const KBTS_LANGUAGE_SAMOGITIAN)++pattern LANGUAGE_SAN_BLAS_KUNA :: Language+pattern LANGUAGE_SAN_BLAS_KUNA = Language (#const KBTS_LANGUAGE_SAN_BLAS_KUNA)++pattern LANGUAGE_SANGO :: Language+pattern LANGUAGE_SANGO = Language (#const KBTS_LANGUAGE_SANGO)++pattern LANGUAGE_SANSKRIT :: Language+pattern LANGUAGE_SANSKRIT = Language (#const KBTS_LANGUAGE_SANSKRIT)++pattern LANGUAGE_SANTALI :: Language+pattern LANGUAGE_SANTALI = Language (#const KBTS_LANGUAGE_SANTALI)++pattern LANGUAGE_SARAIKI :: Language+pattern LANGUAGE_SARAIKI = Language (#const KBTS_LANGUAGE_SARAIKI)++pattern LANGUAGE_SARDINIAN :: Language+pattern LANGUAGE_SARDINIAN = Language (#const KBTS_LANGUAGE_SARDINIAN)++pattern LANGUAGE_SASAK :: Language+pattern LANGUAGE_SASAK = Language (#const KBTS_LANGUAGE_SASAK)++pattern LANGUAGE_SATERLAND_FRISIAN :: Language+pattern LANGUAGE_SATERLAND_FRISIAN = Language (#const KBTS_LANGUAGE_SATERLAND_FRISIAN)++pattern LANGUAGE_SAYISI :: Language+pattern LANGUAGE_SAYISI = Language (#const KBTS_LANGUAGE_SAYISI)++pattern LANGUAGE_SCOTS :: Language+pattern LANGUAGE_SCOTS = Language (#const KBTS_LANGUAGE_SCOTS)++pattern LANGUAGE_SCOTTISH_GAELIC :: Language+pattern LANGUAGE_SCOTTISH_GAELIC = Language (#const KBTS_LANGUAGE_SCOTTISH_GAELIC)++pattern LANGUAGE_SEKOTA :: Language+pattern LANGUAGE_SEKOTA = Language (#const KBTS_LANGUAGE_SEKOTA)++pattern LANGUAGE_SELKUP :: Language+pattern LANGUAGE_SELKUP = Language (#const KBTS_LANGUAGE_SELKUP)++pattern LANGUAGE_SENA :: Language+pattern LANGUAGE_SENA = Language (#const KBTS_LANGUAGE_SENA)++pattern LANGUAGE_SENECA :: Language+pattern LANGUAGE_SENECA = Language (#const KBTS_LANGUAGE_SENECA)++pattern LANGUAGE_SERBIAN :: Language+pattern LANGUAGE_SERBIAN = Language (#const KBTS_LANGUAGE_SERBIAN)++pattern LANGUAGE_SERER :: Language+pattern LANGUAGE_SERER = Language (#const KBTS_LANGUAGE_SERER)++pattern LANGUAGE_SGAW_KAREN :: Language+pattern LANGUAGE_SGAW_KAREN = Language (#const KBTS_LANGUAGE_SGAW_KAREN)++pattern LANGUAGE_SHAN :: Language+pattern LANGUAGE_SHAN = Language (#const KBTS_LANGUAGE_SHAN)++pattern LANGUAGE_SHONA :: Language+pattern LANGUAGE_SHONA = Language (#const KBTS_LANGUAGE_SHONA)++pattern LANGUAGE_SIBE :: Language+pattern LANGUAGE_SIBE = Language (#const KBTS_LANGUAGE_SIBE)++pattern LANGUAGE_SICILIAN :: Language+pattern LANGUAGE_SICILIAN = Language (#const KBTS_LANGUAGE_SICILIAN)++pattern LANGUAGE_SIDAMO :: Language+pattern LANGUAGE_SIDAMO = Language (#const KBTS_LANGUAGE_SIDAMO)++pattern LANGUAGE_SILESIAN :: Language+pattern LANGUAGE_SILESIAN = Language (#const KBTS_LANGUAGE_SILESIAN)++pattern LANGUAGE_SILTE_GURAGE :: Language+pattern LANGUAGE_SILTE_GURAGE = Language (#const KBTS_LANGUAGE_SILTE_GURAGE)++pattern LANGUAGE_SINDHI :: Language+pattern LANGUAGE_SINDHI = Language (#const KBTS_LANGUAGE_SINDHI)++pattern LANGUAGE_SINHALA :: Language+pattern LANGUAGE_SINHALA = Language (#const KBTS_LANGUAGE_SINHALA)++pattern LANGUAGE_SKOLT_SAMI :: Language+pattern LANGUAGE_SKOLT_SAMI = Language (#const KBTS_LANGUAGE_SKOLT_SAMI)++pattern LANGUAGE_SLAVEY :: Language+pattern LANGUAGE_SLAVEY = Language (#const KBTS_LANGUAGE_SLAVEY)++pattern LANGUAGE_SLOVAK :: Language+pattern LANGUAGE_SLOVAK = Language (#const KBTS_LANGUAGE_SLOVAK)++pattern LANGUAGE_SLOVENIAN :: Language+pattern LANGUAGE_SLOVENIAN = Language (#const KBTS_LANGUAGE_SLOVENIAN)++pattern LANGUAGE_SMALL_FLOWERY_MIAO :: Language+pattern LANGUAGE_SMALL_FLOWERY_MIAO = Language (#const KBTS_LANGUAGE_SMALL_FLOWERY_MIAO)++pattern LANGUAGE_SODO_GURAGE :: Language+pattern LANGUAGE_SODO_GURAGE = Language (#const KBTS_LANGUAGE_SODO_GURAGE)++pattern LANGUAGE_SOGA :: Language+pattern LANGUAGE_SOGA = Language (#const KBTS_LANGUAGE_SOGA)++pattern LANGUAGE_SOMALI :: Language+pattern LANGUAGE_SOMALI = Language (#const KBTS_LANGUAGE_SOMALI)++pattern LANGUAGE_SONGE :: Language+pattern LANGUAGE_SONGE = Language (#const KBTS_LANGUAGE_SONGE)++pattern LANGUAGE_SONINKE :: Language+pattern LANGUAGE_SONINKE = Language (#const KBTS_LANGUAGE_SONINKE)++pattern LANGUAGE_SOUTH_SLAVEY :: Language+pattern LANGUAGE_SOUTH_SLAVEY = Language (#const KBTS_LANGUAGE_SOUTH_SLAVEY)++pattern LANGUAGE_SOUTHERN_KIWAI :: Language+pattern LANGUAGE_SOUTHERN_KIWAI = Language (#const KBTS_LANGUAGE_SOUTHERN_KIWAI)++pattern LANGUAGE_SOUTHERN_SAMI :: Language+pattern LANGUAGE_SOUTHERN_SAMI = Language (#const KBTS_LANGUAGE_SOUTHERN_SAMI)++pattern LANGUAGE_SOUTHERN_SOTHO :: Language+pattern LANGUAGE_SOUTHERN_SOTHO = Language (#const KBTS_LANGUAGE_SOUTHERN_SOTHO)++pattern LANGUAGE_SPANISH :: Language+pattern LANGUAGE_SPANISH = Language (#const KBTS_LANGUAGE_SPANISH)++pattern LANGUAGE_STANDARD_MOROCCAN_TAMAZIGHT :: Language+pattern LANGUAGE_STANDARD_MOROCCAN_TAMAZIGHT = Language (#const KBTS_LANGUAGE_STANDARD_MOROCCAN_TAMAZIGHT)++pattern LANGUAGE_STRAITS_SALISH :: Language+pattern LANGUAGE_STRAITS_SALISH = Language (#const KBTS_LANGUAGE_STRAITS_SALISH)++pattern LANGUAGE_SUKUMA :: Language+pattern LANGUAGE_SUKUMA = Language (#const KBTS_LANGUAGE_SUKUMA)++pattern LANGUAGE_SUNDANESE :: Language+pattern LANGUAGE_SUNDANESE = Language (#const KBTS_LANGUAGE_SUNDANESE)++pattern LANGUAGE_SURI :: Language+pattern LANGUAGE_SURI = Language (#const KBTS_LANGUAGE_SURI)++pattern LANGUAGE_SUTU :: Language+pattern LANGUAGE_SUTU = Language (#const KBTS_LANGUAGE_SUTU)++pattern LANGUAGE_SVAN :: Language+pattern LANGUAGE_SVAN = Language (#const KBTS_LANGUAGE_SVAN)++pattern LANGUAGE_SWADAYA_ARAMAIC :: Language+pattern LANGUAGE_SWADAYA_ARAMAIC = Language (#const KBTS_LANGUAGE_SWADAYA_ARAMAIC)++pattern LANGUAGE_SWAHILI :: Language+pattern LANGUAGE_SWAHILI = Language (#const KBTS_LANGUAGE_SWAHILI)++pattern LANGUAGE_SWATI :: Language+pattern LANGUAGE_SWATI = Language (#const KBTS_LANGUAGE_SWATI)++pattern LANGUAGE_SWEDISH :: Language+pattern LANGUAGE_SWEDISH = Language (#const KBTS_LANGUAGE_SWEDISH)++pattern LANGUAGE_SYLHETI :: Language+pattern LANGUAGE_SYLHETI = Language (#const KBTS_LANGUAGE_SYLHETI)++pattern LANGUAGE_SYRIAC :: Language+pattern LANGUAGE_SYRIAC = Language (#const KBTS_LANGUAGE_SYRIAC)++pattern LANGUAGE_SYRIAC_EASTERN :: Language+pattern LANGUAGE_SYRIAC_EASTERN = Language (#const KBTS_LANGUAGE_SYRIAC_EASTERN)++pattern LANGUAGE_SYRIAC_ESTRANGELA :: Language+pattern LANGUAGE_SYRIAC_ESTRANGELA = Language (#const KBTS_LANGUAGE_SYRIAC_ESTRANGELA)++pattern LANGUAGE_SYRIAC_WESTERN :: Language+pattern LANGUAGE_SYRIAC_WESTERN = Language (#const KBTS_LANGUAGE_SYRIAC_WESTERN)++pattern LANGUAGE_TABASARAN :: Language+pattern LANGUAGE_TABASARAN = Language (#const KBTS_LANGUAGE_TABASARAN)++pattern LANGUAGE_TACHELHIT :: Language+pattern LANGUAGE_TACHELHIT = Language (#const KBTS_LANGUAGE_TACHELHIT)++pattern LANGUAGE_TAGALOG :: Language+pattern LANGUAGE_TAGALOG = Language (#const KBTS_LANGUAGE_TAGALOG)++pattern LANGUAGE_TAHAGGART_TAMAHAQ :: Language+pattern LANGUAGE_TAHAGGART_TAMAHAQ = Language (#const KBTS_LANGUAGE_TAHAGGART_TAMAHAQ)++pattern LANGUAGE_TAHITIAN :: Language+pattern LANGUAGE_TAHITIAN = Language (#const KBTS_LANGUAGE_TAHITIAN)++pattern LANGUAGE_TAI_LAING :: Language+pattern LANGUAGE_TAI_LAING = Language (#const KBTS_LANGUAGE_TAI_LAING)++pattern LANGUAGE_TAJIKI :: Language+pattern LANGUAGE_TAJIKI = Language (#const KBTS_LANGUAGE_TAJIKI)++pattern LANGUAGE_TALYSH :: Language+pattern LANGUAGE_TALYSH = Language (#const KBTS_LANGUAGE_TALYSH)++pattern LANGUAGE_TAMASHEK :: Language+pattern LANGUAGE_TAMASHEK = Language (#const KBTS_LANGUAGE_TAMASHEK)++pattern LANGUAGE_TAMASHEQ :: Language+pattern LANGUAGE_TAMASHEQ = Language (#const KBTS_LANGUAGE_TAMASHEQ)++pattern LANGUAGE_TAMAZIGHT :: Language+pattern LANGUAGE_TAMAZIGHT = Language (#const KBTS_LANGUAGE_TAMAZIGHT)++pattern LANGUAGE_TAMIL :: Language+pattern LANGUAGE_TAMIL = Language (#const KBTS_LANGUAGE_TAMIL)++pattern LANGUAGE_TARIFIT :: Language+pattern LANGUAGE_TARIFIT = Language (#const KBTS_LANGUAGE_TARIFIT)++pattern LANGUAGE_TATAR :: Language+pattern LANGUAGE_TATAR = Language (#const KBTS_LANGUAGE_TATAR)++pattern LANGUAGE_TAWALLAMMAT_TAMAJAQ :: Language+pattern LANGUAGE_TAWALLAMMAT_TAMAJAQ = Language (#const KBTS_LANGUAGE_TAWALLAMMAT_TAMAJAQ)++pattern LANGUAGE_TAY :: Language+pattern LANGUAGE_TAY = Language (#const KBTS_LANGUAGE_TAY)++pattern LANGUAGE_TAYART_TAMAJEQ :: Language+pattern LANGUAGE_TAYART_TAMAJEQ = Language (#const KBTS_LANGUAGE_TAYART_TAMAJEQ)++pattern LANGUAGE_TELUGU :: Language+pattern LANGUAGE_TELUGU = Language (#const KBTS_LANGUAGE_TELUGU)++pattern LANGUAGE_TEMNE :: Language+pattern LANGUAGE_TEMNE = Language (#const KBTS_LANGUAGE_TEMNE)++pattern LANGUAGE_TETUM :: Language+pattern LANGUAGE_TETUM = Language (#const KBTS_LANGUAGE_TETUM)++pattern LANGUAGE_TH_CREE :: Language+pattern LANGUAGE_TH_CREE = Language (#const KBTS_LANGUAGE_TH_CREE)++pattern LANGUAGE_THAI :: Language+pattern LANGUAGE_THAI = Language (#const KBTS_LANGUAGE_THAI)++pattern LANGUAGE_THAILAND_MON :: Language+pattern LANGUAGE_THAILAND_MON = Language (#const KBTS_LANGUAGE_THAILAND_MON)++pattern LANGUAGE_THOMPSON :: Language+pattern LANGUAGE_THOMPSON = Language (#const KBTS_LANGUAGE_THOMPSON)++pattern LANGUAGE_TIBETAN :: Language+pattern LANGUAGE_TIBETAN = Language (#const KBTS_LANGUAGE_TIBETAN)++pattern LANGUAGE_TIGRE :: Language+pattern LANGUAGE_TIGRE = Language (#const KBTS_LANGUAGE_TIGRE)++pattern LANGUAGE_TIGRINYA :: Language+pattern LANGUAGE_TIGRINYA = Language (#const KBTS_LANGUAGE_TIGRINYA)++pattern LANGUAGE_TIV :: Language+pattern LANGUAGE_TIV = Language (#const KBTS_LANGUAGE_TIV)++pattern LANGUAGE_TLINGIT :: Language+pattern LANGUAGE_TLINGIT = Language (#const KBTS_LANGUAGE_TLINGIT)++pattern LANGUAGE_TOBO :: Language+pattern LANGUAGE_TOBO = Language (#const KBTS_LANGUAGE_TOBO)++pattern LANGUAGE_TODO :: Language+pattern LANGUAGE_TODO = Language (#const KBTS_LANGUAGE_TODO)++pattern LANGUAGE_TOK_PISIN :: Language+pattern LANGUAGE_TOK_PISIN = Language (#const KBTS_LANGUAGE_TOK_PISIN)++pattern LANGUAGE_TOMA :: Language+pattern LANGUAGE_TOMA = Language (#const KBTS_LANGUAGE_TOMA)++pattern LANGUAGE_TONGA :: Language+pattern LANGUAGE_TONGA = Language (#const KBTS_LANGUAGE_TONGA)++pattern LANGUAGE_TONGAN :: Language+pattern LANGUAGE_TONGAN = Language (#const KBTS_LANGUAGE_TONGAN)++pattern LANGUAGE_TORKI :: Language+pattern LANGUAGE_TORKI = Language (#const KBTS_LANGUAGE_TORKI)++pattern LANGUAGE_TSHANGLA :: Language+pattern LANGUAGE_TSHANGLA = Language (#const KBTS_LANGUAGE_TSHANGLA)++pattern LANGUAGE_TSONGA :: Language+pattern LANGUAGE_TSONGA = Language (#const KBTS_LANGUAGE_TSONGA)++pattern LANGUAGE_TSWANA :: Language+pattern LANGUAGE_TSWANA = Language (#const KBTS_LANGUAGE_TSWANA)++pattern LANGUAGE_TULU :: Language+pattern LANGUAGE_TULU = Language (#const KBTS_LANGUAGE_TULU)++pattern LANGUAGE_TUMBUKA :: Language+pattern LANGUAGE_TUMBUKA = Language (#const KBTS_LANGUAGE_TUMBUKA)++pattern LANGUAGE_TUNDRA_ENETS :: Language+pattern LANGUAGE_TUNDRA_ENETS = Language (#const KBTS_LANGUAGE_TUNDRA_ENETS)++pattern LANGUAGE_TURKISH :: Language+pattern LANGUAGE_TURKISH = Language (#const KBTS_LANGUAGE_TURKISH)++pattern LANGUAGE_TURKMEN :: Language+pattern LANGUAGE_TURKMEN = Language (#const KBTS_LANGUAGE_TURKMEN)++pattern LANGUAGE_TUROYO_ARAMAIC :: Language+pattern LANGUAGE_TUROYO_ARAMAIC = Language (#const KBTS_LANGUAGE_TUROYO_ARAMAIC)++pattern LANGUAGE_TUSCARORA :: Language+pattern LANGUAGE_TUSCARORA = Language (#const KBTS_LANGUAGE_TUSCARORA)++pattern LANGUAGE_TUVALU :: Language+pattern LANGUAGE_TUVALU = Language (#const KBTS_LANGUAGE_TUVALU)++pattern LANGUAGE_TUVIN :: Language+pattern LANGUAGE_TUVIN = Language (#const KBTS_LANGUAGE_TUVIN)++pattern LANGUAGE_TWI :: Language+pattern LANGUAGE_TWI = Language (#const KBTS_LANGUAGE_TWI)++pattern LANGUAGE_TZOTZIL :: Language+pattern LANGUAGE_TZOTZIL = Language (#const KBTS_LANGUAGE_TZOTZIL)++pattern LANGUAGE_UDI :: Language+pattern LANGUAGE_UDI = Language (#const KBTS_LANGUAGE_UDI)++pattern LANGUAGE_UDMURT :: Language+pattern LANGUAGE_UDMURT = Language (#const KBTS_LANGUAGE_UDMURT)++pattern LANGUAGE_UKRAINIAN :: Language+pattern LANGUAGE_UKRAINIAN = Language (#const KBTS_LANGUAGE_UKRAINIAN)++pattern LANGUAGE_UMBUNDU :: Language+pattern LANGUAGE_UMBUNDU = Language (#const KBTS_LANGUAGE_UMBUNDU)++pattern LANGUAGE_UME_SAMI :: Language+pattern LANGUAGE_UME_SAMI = Language (#const KBTS_LANGUAGE_UME_SAMI)++pattern LANGUAGE_UPPER_SAXON :: Language+pattern LANGUAGE_UPPER_SAXON = Language (#const KBTS_LANGUAGE_UPPER_SAXON)++pattern LANGUAGE_UPPER_SORBIAN :: Language+pattern LANGUAGE_UPPER_SORBIAN = Language (#const KBTS_LANGUAGE_UPPER_SORBIAN)++pattern LANGUAGE_URALIC_PHONETIC :: Language+pattern LANGUAGE_URALIC_PHONETIC = Language (#const KBTS_LANGUAGE_URALIC_PHONETIC)++pattern LANGUAGE_URDU :: Language+pattern LANGUAGE_URDU = Language (#const KBTS_LANGUAGE_URDU)++pattern LANGUAGE_UYGHUR :: Language+pattern LANGUAGE_UYGHUR = Language (#const KBTS_LANGUAGE_UYGHUR)++pattern LANGUAGE_UZBEK :: Language+pattern LANGUAGE_UZBEK = Language (#const KBTS_LANGUAGE_UZBEK)++pattern LANGUAGE_VENDA :: Language+pattern LANGUAGE_VENDA = Language (#const KBTS_LANGUAGE_VENDA)++pattern LANGUAGE_VENETIAN :: Language+pattern LANGUAGE_VENETIAN = Language (#const KBTS_LANGUAGE_VENETIAN)++pattern LANGUAGE_VIETNAMESE :: Language+pattern LANGUAGE_VIETNAMESE = Language (#const KBTS_LANGUAGE_VIETNAMESE)++pattern LANGUAGE_VLAX_ROMANI :: Language+pattern LANGUAGE_VLAX_ROMANI = Language (#const KBTS_LANGUAGE_VLAX_ROMANI)++pattern LANGUAGE_VOLAPUK :: Language+pattern LANGUAGE_VOLAPUK = Language (#const KBTS_LANGUAGE_VOLAPUK)++pattern LANGUAGE_VORO :: Language+pattern LANGUAGE_VORO = Language (#const KBTS_LANGUAGE_VORO)++pattern LANGUAGE_WA :: Language+pattern LANGUAGE_WA = Language (#const KBTS_LANGUAGE_WA)++pattern LANGUAGE_WACI_GBE :: Language+pattern LANGUAGE_WACI_GBE = Language (#const KBTS_LANGUAGE_WACI_GBE)++pattern LANGUAGE_WAGDI :: Language+pattern LANGUAGE_WAGDI = Language (#const KBTS_LANGUAGE_WAGDI)++pattern LANGUAGE_WAKHI :: Language+pattern LANGUAGE_WAKHI = Language (#const KBTS_LANGUAGE_WAKHI)++pattern LANGUAGE_WALLOON :: Language+pattern LANGUAGE_WALLOON = Language (#const KBTS_LANGUAGE_WALLOON)++pattern LANGUAGE_WARAY_WARAY :: Language+pattern LANGUAGE_WARAY_WARAY = Language (#const KBTS_LANGUAGE_WARAY_WARAY)++pattern LANGUAGE_WAYANAD_CHETTI :: Language+pattern LANGUAGE_WAYANAD_CHETTI = Language (#const KBTS_LANGUAGE_WAYANAD_CHETTI)++pattern LANGUAGE_WAYUU :: Language+pattern LANGUAGE_WAYUU = Language (#const KBTS_LANGUAGE_WAYUU)++pattern LANGUAGE_WELSH :: Language+pattern LANGUAGE_WELSH = Language (#const KBTS_LANGUAGE_WELSH)++pattern LANGUAGE_WENDAT :: Language+pattern LANGUAGE_WENDAT = Language (#const KBTS_LANGUAGE_WENDAT)++pattern LANGUAGE_WEST_CREE :: Language+pattern LANGUAGE_WEST_CREE = Language (#const KBTS_LANGUAGE_WEST_CREE)++pattern LANGUAGE_WESTERN_CHAM :: Language+pattern LANGUAGE_WESTERN_CHAM = Language (#const KBTS_LANGUAGE_WESTERN_CHAM)++pattern LANGUAGE_WESTERN_KAYAH :: Language+pattern LANGUAGE_WESTERN_KAYAH = Language (#const KBTS_LANGUAGE_WESTERN_KAYAH)++pattern LANGUAGE_WESTERN_PANJABI :: Language+pattern LANGUAGE_WESTERN_PANJABI = Language (#const KBTS_LANGUAGE_WESTERN_PANJABI)++pattern LANGUAGE_WESTERN_PWO_KAREN :: Language+pattern LANGUAGE_WESTERN_PWO_KAREN = Language (#const KBTS_LANGUAGE_WESTERN_PWO_KAREN)++pattern LANGUAGE_WOLOF :: Language+pattern LANGUAGE_WOLOF = Language (#const KBTS_LANGUAGE_WOLOF)++pattern LANGUAGE_WOODS_CREE :: Language+pattern LANGUAGE_WOODS_CREE = Language (#const KBTS_LANGUAGE_WOODS_CREE)++pattern LANGUAGE_WUDING_LUQUAN_YI :: Language+pattern LANGUAGE_WUDING_LUQUAN_YI = Language (#const KBTS_LANGUAGE_WUDING_LUQUAN_YI)++pattern LANGUAGE_WYANDOT :: Language+pattern LANGUAGE_WYANDOT = Language (#const KBTS_LANGUAGE_WYANDOT)++pattern LANGUAGE_XHOSA :: Language+pattern LANGUAGE_XHOSA = Language (#const KBTS_LANGUAGE_XHOSA)++pattern LANGUAGE_Y_CREE :: Language+pattern LANGUAGE_Y_CREE = Language (#const KBTS_LANGUAGE_Y_CREE)++pattern LANGUAGE_YAO :: Language+pattern LANGUAGE_YAO = Language (#const KBTS_LANGUAGE_YAO)++pattern LANGUAGE_YAPESE :: Language+pattern LANGUAGE_YAPESE = Language (#const KBTS_LANGUAGE_YAPESE)++pattern LANGUAGE_YI_CLASSIC :: Language+pattern LANGUAGE_YI_CLASSIC = Language (#const KBTS_LANGUAGE_YI_CLASSIC)++pattern LANGUAGE_YI_MODERN :: Language+pattern LANGUAGE_YI_MODERN = Language (#const KBTS_LANGUAGE_YI_MODERN)++pattern LANGUAGE_YIDDISH :: Language+pattern LANGUAGE_YIDDISH = Language (#const KBTS_LANGUAGE_YIDDISH)++pattern LANGUAGE_YORUBA :: Language+pattern LANGUAGE_YORUBA = Language (#const KBTS_LANGUAGE_YORUBA)++pattern LANGUAGE_ZAMBOANGA_CHAVACANO :: Language+pattern LANGUAGE_ZAMBOANGA_CHAVACANO = Language (#const KBTS_LANGUAGE_ZAMBOANGA_CHAVACANO)++pattern LANGUAGE_ZANDE :: Language+pattern LANGUAGE_ZANDE = Language (#const KBTS_LANGUAGE_ZANDE)++pattern LANGUAGE_ZARMA :: Language+pattern LANGUAGE_ZARMA = Language (#const KBTS_LANGUAGE_ZARMA)++pattern LANGUAGE_ZAZAKI :: Language+pattern LANGUAGE_ZAZAKI = Language (#const KBTS_LANGUAGE_ZAZAKI)++pattern LANGUAGE_ZEALANDIC :: Language+pattern LANGUAGE_ZEALANDIC = Language (#const KBTS_LANGUAGE_ZEALANDIC)++pattern LANGUAGE_ZHUANG :: Language+pattern LANGUAGE_ZHUANG = Language (#const KBTS_LANGUAGE_ZHUANG)++pattern LANGUAGE_ZULU :: Language+pattern LANGUAGE_ZULU = Language (#const KBTS_LANGUAGE_ZULU)++languageNames :: Map Language String+languageNames = Map.fromList+ [ (LANGUAGE_DONT_KNOW, "LANGUAGE_DONT_KNOW")+ , (LANGUAGE_A_HMAO, "LANGUAGE_A_HMAO")+ , (LANGUAGE_AARI, "LANGUAGE_AARI")+ , (LANGUAGE_ABAZA, "LANGUAGE_ABAZA")+ , (LANGUAGE_ABKHAZIAN, "LANGUAGE_ABKHAZIAN")+ , (LANGUAGE_ACHI, "LANGUAGE_ACHI")+ , (LANGUAGE_ACHOLI, "LANGUAGE_ACHOLI")+ , (LANGUAGE_ADYGHE, "LANGUAGE_ADYGHE")+ , (LANGUAGE_AFAR, "LANGUAGE_AFAR")+ , (LANGUAGE_AFRIKAANS, "LANGUAGE_AFRIKAANS")+ , (LANGUAGE_AGAW, "LANGUAGE_AGAW")+ , (LANGUAGE_AITON, "LANGUAGE_AITON")+ , (LANGUAGE_AKAN, "LANGUAGE_AKAN")+ , (LANGUAGE_ALBANIAN, "LANGUAGE_ALBANIAN")+ , (LANGUAGE_ALSATIAN, "LANGUAGE_ALSATIAN")+ , (LANGUAGE_ALTAI, "LANGUAGE_ALTAI")+ , (LANGUAGE_ALUO, "LANGUAGE_ALUO")+ , (LANGUAGE_AMERICAN_PHONETIC, "LANGUAGE_AMERICAN_PHONETIC")+ , (LANGUAGE_AMHARIC, "LANGUAGE_AMHARIC")+ , (LANGUAGE_ANGLO_SAXON, "LANGUAGE_ANGLO_SAXON")+ , (LANGUAGE_ARABIC, "LANGUAGE_ARABIC")+ , (LANGUAGE_ARAGONESE, "LANGUAGE_ARAGONESE")+ , (LANGUAGE_ARAKANESE, "LANGUAGE_ARAKANESE")+ , (LANGUAGE_ARAKWAL, "LANGUAGE_ARAKWAL")+ , (LANGUAGE_ARMENIAN, "LANGUAGE_ARMENIAN")+ , (LANGUAGE_ARMENIAN_EAST, "LANGUAGE_ARMENIAN_EAST")+ , (LANGUAGE_AROMANIAN, "LANGUAGE_AROMANIAN")+ , (LANGUAGE_ARPITAN, "LANGUAGE_ARPITAN")+ , (LANGUAGE_ASSAMESE, "LANGUAGE_ASSAMESE")+ , (LANGUAGE_ASTURIAN, "LANGUAGE_ASTURIAN")+ , (LANGUAGE_ATHAPASKAN, "LANGUAGE_ATHAPASKAN")+ , (LANGUAGE_ATSINA, "LANGUAGE_ATSINA")+ , (LANGUAGE_AVAR, "LANGUAGE_AVAR")+ , (LANGUAGE_AVATIME, "LANGUAGE_AVATIME")+ , (LANGUAGE_AWADHI, "LANGUAGE_AWADHI")+ , (LANGUAGE_AYMARA, "LANGUAGE_AYMARA")+ , (LANGUAGE_AZERBAIDJANI, "LANGUAGE_AZERBAIDJANI")+ , (LANGUAGE_BADAGA, "LANGUAGE_BADAGA")+ , (LANGUAGE_BAGHELKHANDI, "LANGUAGE_BAGHELKHANDI")+ , (LANGUAGE_BAGRI, "LANGUAGE_BAGRI")+ , (LANGUAGE_BALANTE, "LANGUAGE_BALANTE")+ , (LANGUAGE_BALINESE, "LANGUAGE_BALINESE")+ , (LANGUAGE_BALKAR, "LANGUAGE_BALKAR")+ , (LANGUAGE_BALTI, "LANGUAGE_BALTI")+ , (LANGUAGE_BALUCHI, "LANGUAGE_BALUCHI")+ , (LANGUAGE_BAMBARA, "LANGUAGE_BAMBARA")+ , (LANGUAGE_BAMILEKE, "LANGUAGE_BAMILEKE")+ , (LANGUAGE_BANDA, "LANGUAGE_BANDA")+ , (LANGUAGE_BANDJALANG, "LANGUAGE_BANDJALANG")+ , (LANGUAGE_BANGLA, "LANGUAGE_BANGLA")+ , (LANGUAGE_BASHKIR, "LANGUAGE_BASHKIR")+ , (LANGUAGE_BASQUE, "LANGUAGE_BASQUE")+ , (LANGUAGE_BATAK, "LANGUAGE_BATAK")+ , (LANGUAGE_BATAK_ALAS_KLUET, "LANGUAGE_BATAK_ALAS_KLUET")+ , (LANGUAGE_BATAK_ANGKOLA, "LANGUAGE_BATAK_ANGKOLA")+ , (LANGUAGE_BATAK_DAIRI, "LANGUAGE_BATAK_DAIRI")+ , (LANGUAGE_BATAK_KARO, "LANGUAGE_BATAK_KARO")+ , (LANGUAGE_BATAK_MANDAILING, "LANGUAGE_BATAK_MANDAILING")+ , (LANGUAGE_BATAK_SIMALUNGUN, "LANGUAGE_BATAK_SIMALUNGUN")+ , (LANGUAGE_BATAK_TOBA, "LANGUAGE_BATAK_TOBA")+ , (LANGUAGE_BAULE, "LANGUAGE_BAULE")+ , (LANGUAGE_BAVARIAN, "LANGUAGE_BAVARIAN")+ , (LANGUAGE_BELARUSIAN, "LANGUAGE_BELARUSIAN")+ , (LANGUAGE_BEMBA, "LANGUAGE_BEMBA")+ , (LANGUAGE_BENCH, "LANGUAGE_BENCH")+ , (LANGUAGE_BERBER, "LANGUAGE_BERBER")+ , (LANGUAGE_BETI, "LANGUAGE_BETI")+ , (LANGUAGE_BETTE_KURUMA, "LANGUAGE_BETTE_KURUMA")+ , (LANGUAGE_BHILI, "LANGUAGE_BHILI")+ , (LANGUAGE_BHOJPURI, "LANGUAGE_BHOJPURI")+ , (LANGUAGE_BHUTANESE, "LANGUAGE_BHUTANESE")+ , (LANGUAGE_BIBLE_CREE, "LANGUAGE_BIBLE_CREE")+ , (LANGUAGE_BIKOL, "LANGUAGE_BIKOL")+ , (LANGUAGE_BILEN, "LANGUAGE_BILEN")+ , (LANGUAGE_BISHNUPRIYA_MANIPURI, "LANGUAGE_BISHNUPRIYA_MANIPURI")+ , (LANGUAGE_BISLAMA, "LANGUAGE_BISLAMA")+ , (LANGUAGE_BLACKFOOT, "LANGUAGE_BLACKFOOT")+ , (LANGUAGE_BODO, "LANGUAGE_BODO")+ , (LANGUAGE_BOSNIAN, "LANGUAGE_BOSNIAN")+ , (LANGUAGE_BOUYEI, "LANGUAGE_BOUYEI")+ , (LANGUAGE_BRAHUI, "LANGUAGE_BRAHUI")+ , (LANGUAGE_BRAJ_BHASHA, "LANGUAGE_BRAJ_BHASHA")+ , (LANGUAGE_BRETON, "LANGUAGE_BRETON")+ , (LANGUAGE_BUGIS, "LANGUAGE_BUGIS")+ , (LANGUAGE_BULGARIAN, "LANGUAGE_BULGARIAN")+ , (LANGUAGE_BUMTHANGKHA, "LANGUAGE_BUMTHANGKHA")+ , (LANGUAGE_BURMESE, "LANGUAGE_BURMESE")+ , (LANGUAGE_BURUSHASKI, "LANGUAGE_BURUSHASKI")+ , (LANGUAGE_CAJUN_FRENCH, "LANGUAGE_CAJUN_FRENCH")+ , (LANGUAGE_CARRIER, "LANGUAGE_CARRIER")+ , (LANGUAGE_CATALAN, "LANGUAGE_CATALAN")+ , (LANGUAGE_CAYUGA, "LANGUAGE_CAYUGA")+ , (LANGUAGE_CEBUANO, "LANGUAGE_CEBUANO")+ , (LANGUAGE_CENTRAL_YUPIK, "LANGUAGE_CENTRAL_YUPIK")+ , (LANGUAGE_CHAHA_GURAGE, "LANGUAGE_CHAHA_GURAGE")+ , (LANGUAGE_CHAMORRO, "LANGUAGE_CHAMORRO")+ , (LANGUAGE_CHATTISGARHI, "LANGUAGE_CHATTISGARHI")+ , (LANGUAGE_CHECHEN, "LANGUAGE_CHECHEN")+ , (LANGUAGE_CHEROKEE, "LANGUAGE_CHEROKEE")+ , (LANGUAGE_CHEYENNE, "LANGUAGE_CHEYENNE")+ , (LANGUAGE_CHICHEWA, "LANGUAGE_CHICHEWA")+ , (LANGUAGE_CHIGA, "LANGUAGE_CHIGA")+ , (LANGUAGE_CHIMILA, "LANGUAGE_CHIMILA")+ , (LANGUAGE_CHIN, "LANGUAGE_CHIN")+ , (LANGUAGE_CHINANTEC, "LANGUAGE_CHINANTEC")+ , (LANGUAGE_CHINESE_PHONETIC, "LANGUAGE_CHINESE_PHONETIC")+ , (LANGUAGE_CHINESE_SIMPLIFIED, "LANGUAGE_CHINESE_SIMPLIFIED")+ , (LANGUAGE_CHINESE_TRADITIONAL, "LANGUAGE_CHINESE_TRADITIONAL")+ , (LANGUAGE_CHINESE_TRADITIONAL_HONG_KONG, "LANGUAGE_CHINESE_TRADITIONAL_HONG_KONG")+ , (LANGUAGE_CHINESE_TRADITIONAL_MACAO, "LANGUAGE_CHINESE_TRADITIONAL_MACAO")+ , (LANGUAGE_CHIPEWYAN, "LANGUAGE_CHIPEWYAN")+ , (LANGUAGE_CHITTAGONIAN, "LANGUAGE_CHITTAGONIAN")+ , (LANGUAGE_CHOCTAW, "LANGUAGE_CHOCTAW")+ , (LANGUAGE_CHUKCHI, "LANGUAGE_CHUKCHI")+ , (LANGUAGE_CHURCH_SLAVONIC, "LANGUAGE_CHURCH_SLAVONIC")+ , (LANGUAGE_CHUUKESE, "LANGUAGE_CHUUKESE")+ , (LANGUAGE_CHUVASH, "LANGUAGE_CHUVASH")+ , (LANGUAGE_COMORIAN, "LANGUAGE_COMORIAN")+ , (LANGUAGE_COMOX, "LANGUAGE_COMOX")+ , (LANGUAGE_COPTIC, "LANGUAGE_COPTIC")+ , (LANGUAGE_CORNISH, "LANGUAGE_CORNISH")+ , (LANGUAGE_CORSICAN, "LANGUAGE_CORSICAN")+ , (LANGUAGE_CREE, "LANGUAGE_CREE")+ , (LANGUAGE_CREOLES, "LANGUAGE_CREOLES")+ , (LANGUAGE_CRIMEAN_TATAR, "LANGUAGE_CRIMEAN_TATAR")+ , (LANGUAGE_CRIOULO, "LANGUAGE_CRIOULO")+ , (LANGUAGE_CROATIAN, "LANGUAGE_CROATIAN")+ , (LANGUAGE_CYPRIOT_ARABIC, "LANGUAGE_CYPRIOT_ARABIC")+ , (LANGUAGE_CZECH, "LANGUAGE_CZECH")+ , (LANGUAGE_DAGBANI, "LANGUAGE_DAGBANI")+ , (LANGUAGE_DAN, "LANGUAGE_DAN")+ , (LANGUAGE_DANGME, "LANGUAGE_DANGME")+ , (LANGUAGE_DANISH, "LANGUAGE_DANISH")+ , (LANGUAGE_DARGWA, "LANGUAGE_DARGWA")+ , (LANGUAGE_DARI, "LANGUAGE_DARI")+ , (LANGUAGE_DAYI, "LANGUAGE_DAYI")+ , (LANGUAGE_DEFAULT, "LANGUAGE_DEFAULT")+ , (LANGUAGE_DEHONG_DAI, "LANGUAGE_DEHONG_DAI")+ , (LANGUAGE_DHANGU, "LANGUAGE_DHANGU")+ , (LANGUAGE_DHIVEHI, "LANGUAGE_DHIVEHI")+ , (LANGUAGE_DHUWAL, "LANGUAGE_DHUWAL")+ , (LANGUAGE_DIMLI, "LANGUAGE_DIMLI")+ , (LANGUAGE_DINKA, "LANGUAGE_DINKA")+ , (LANGUAGE_DIVEHI, "LANGUAGE_DIVEHI")+ , (LANGUAGE_DJAMBARRPUYNGU, "LANGUAGE_DJAMBARRPUYNGU")+ , (LANGUAGE_DOGRI, "LANGUAGE_DOGRI")+ , (LANGUAGE_DOGRI_MACROLANGUAGE, "LANGUAGE_DOGRI_MACROLANGUAGE")+ , (LANGUAGE_DUNGAN, "LANGUAGE_DUNGAN")+ , (LANGUAGE_DUTCH, "LANGUAGE_DUTCH")+ , (LANGUAGE_DZONGKHA, "LANGUAGE_DZONGKHA")+ , (LANGUAGE_EASTERN_ABENAKI, "LANGUAGE_EASTERN_ABENAKI")+ , (LANGUAGE_EASTERN_CHAM, "LANGUAGE_EASTERN_CHAM")+ , (LANGUAGE_EASTERN_CREE, "LANGUAGE_EASTERN_CREE")+ , (LANGUAGE_EASTERN_MANINKAKAN, "LANGUAGE_EASTERN_MANINKAKAN")+ , (LANGUAGE_EASTERN_PWO_KAREN, "LANGUAGE_EASTERN_PWO_KAREN")+ , (LANGUAGE_EBIRA, "LANGUAGE_EBIRA")+ , (LANGUAGE_EDO, "LANGUAGE_EDO")+ , (LANGUAGE_EFIK, "LANGUAGE_EFIK")+ , (LANGUAGE_EMBERA_BAUDO, "LANGUAGE_EMBERA_BAUDO")+ , (LANGUAGE_EMBERA_CATIO, "LANGUAGE_EMBERA_CATIO")+ , (LANGUAGE_EMBERA_CHAMI, "LANGUAGE_EMBERA_CHAMI")+ , (LANGUAGE_EMBERA_TADO, "LANGUAGE_EMBERA_TADO")+ , (LANGUAGE_ENGLISH, "LANGUAGE_ENGLISH")+ , (LANGUAGE_EPENA, "LANGUAGE_EPENA")+ , (LANGUAGE_ERZYA, "LANGUAGE_ERZYA")+ , (LANGUAGE_KB_TEXT_SHAPEANTO, "LANGUAGE_KB_TEXT_SHAPEANTO")+ , (LANGUAGE_ESTONIAN, "LANGUAGE_ESTONIAN")+ , (LANGUAGE_EVEN, "LANGUAGE_EVEN")+ , (LANGUAGE_EVENKI, "LANGUAGE_EVENKI")+ , (LANGUAGE_EWE, "LANGUAGE_EWE")+ , (LANGUAGE_FALAM_CHIN, "LANGUAGE_FALAM_CHIN")+ , (LANGUAGE_FANG, "LANGUAGE_FANG")+ , (LANGUAGE_FANTI, "LANGUAGE_FANTI")+ , (LANGUAGE_FAROESE, "LANGUAGE_FAROESE")+ , (LANGUAGE_FEFE, "LANGUAGE_FEFE")+ , (LANGUAGE_FIJIAN, "LANGUAGE_FIJIAN")+ , (LANGUAGE_FILIPINO, "LANGUAGE_FILIPINO")+ , (LANGUAGE_FINNISH, "LANGUAGE_FINNISH")+ , (LANGUAGE_FLEMISH, "LANGUAGE_FLEMISH")+ , (LANGUAGE_FON, "LANGUAGE_FON")+ , (LANGUAGE_FOREST_ENETS, "LANGUAGE_FOREST_ENETS")+ , (LANGUAGE_FRENCH, "LANGUAGE_FRENCH")+ , (LANGUAGE_FRENCH_ANTILLEAN, "LANGUAGE_FRENCH_ANTILLEAN")+ , (LANGUAGE_FRISIAN, "LANGUAGE_FRISIAN")+ , (LANGUAGE_FRIULIAN, "LANGUAGE_FRIULIAN")+ , (LANGUAGE_FULAH, "LANGUAGE_FULAH")+ , (LANGUAGE_FUTA, "LANGUAGE_FUTA")+ , (LANGUAGE_GA, "LANGUAGE_GA")+ , (LANGUAGE_GAGAUZ, "LANGUAGE_GAGAUZ")+ , (LANGUAGE_GALICIAN, "LANGUAGE_GALICIAN")+ , (LANGUAGE_GANDA, "LANGUAGE_GANDA")+ , (LANGUAGE_GARHWALI, "LANGUAGE_GARHWALI")+ , (LANGUAGE_GARO, "LANGUAGE_GARO")+ , (LANGUAGE_GARSHUNI, "LANGUAGE_GARSHUNI")+ , (LANGUAGE_GEBA_KAREN, "LANGUAGE_GEBA_KAREN")+ , (LANGUAGE_GEEZ, "LANGUAGE_GEEZ")+ , (LANGUAGE_GEORGIAN, "LANGUAGE_GEORGIAN")+ , (LANGUAGE_GEPO, "LANGUAGE_GEPO")+ , (LANGUAGE_GERMAN, "LANGUAGE_GERMAN")+ , (LANGUAGE_GIKUYU, "LANGUAGE_GIKUYU")+ , (LANGUAGE_GILAKI, "LANGUAGE_GILAKI")+ , (LANGUAGE_GILBERTESE, "LANGUAGE_GILBERTESE")+ , (LANGUAGE_GILYAK, "LANGUAGE_GILYAK")+ , (LANGUAGE_GITHABUL, "LANGUAGE_GITHABUL")+ , (LANGUAGE_GOGO, "LANGUAGE_GOGO")+ , (LANGUAGE_GONDI, "LANGUAGE_GONDI")+ , (LANGUAGE_GREEK, "LANGUAGE_GREEK")+ , (LANGUAGE_GREENLANDIC, "LANGUAGE_GREENLANDIC")+ , (LANGUAGE_GUARANI, "LANGUAGE_GUARANI")+ , (LANGUAGE_GUINEA, "LANGUAGE_GUINEA")+ , (LANGUAGE_GUJARATI, "LANGUAGE_GUJARATI")+ , (LANGUAGE_GUMATJ, "LANGUAGE_GUMATJ")+ , (LANGUAGE_GUMUZ, "LANGUAGE_GUMUZ")+ , (LANGUAGE_GUPAPUYNGU, "LANGUAGE_GUPAPUYNGU")+ , (LANGUAGE_GUSII, "LANGUAGE_GUSII")+ , (LANGUAGE_HAIDA, "LANGUAGE_HAIDA")+ , (LANGUAGE_HAITIAN_CREOLE, "LANGUAGE_HAITIAN_CREOLE")+ , (LANGUAGE_HALKOMELEM, "LANGUAGE_HALKOMELEM")+ , (LANGUAGE_HAMMER_BANNA, "LANGUAGE_HAMMER_BANNA")+ , (LANGUAGE_HARARI, "LANGUAGE_HARARI")+ , (LANGUAGE_HARAUTI, "LANGUAGE_HARAUTI")+ , (LANGUAGE_HARYANVI, "LANGUAGE_HARYANVI")+ , (LANGUAGE_HAUSA, "LANGUAGE_HAUSA")+ , (LANGUAGE_HAVASUPAI_WALAPAI_YAVAPAI, "LANGUAGE_HAVASUPAI_WALAPAI_YAVAPAI")+ , (LANGUAGE_HAWAIIAN, "LANGUAGE_HAWAIIAN")+ , (LANGUAGE_HAYA, "LANGUAGE_HAYA")+ , (LANGUAGE_HAZARAGI, "LANGUAGE_HAZARAGI")+ , (LANGUAGE_HEBREW, "LANGUAGE_HEBREW")+ , (LANGUAGE_HEILTSUK, "LANGUAGE_HEILTSUK")+ , (LANGUAGE_HERERO, "LANGUAGE_HERERO")+ , (LANGUAGE_HIGH_MARI, "LANGUAGE_HIGH_MARI")+ , (LANGUAGE_HILIGAYNON, "LANGUAGE_HILIGAYNON")+ , (LANGUAGE_HINDI, "LANGUAGE_HINDI")+ , (LANGUAGE_HINDKO, "LANGUAGE_HINDKO")+ , (LANGUAGE_HIRI_MOTU, "LANGUAGE_HIRI_MOTU")+ , (LANGUAGE_HMONG, "LANGUAGE_HMONG")+ , (LANGUAGE_HMONG_DAW, "LANGUAGE_HMONG_DAW")+ , (LANGUAGE_HMONG_SHUAT, "LANGUAGE_HMONG_SHUAT")+ , (LANGUAGE_HO, "LANGUAGE_HO")+ , (LANGUAGE_HUNGARIAN, "LANGUAGE_HUNGARIAN")+ , (LANGUAGE_IBAN, "LANGUAGE_IBAN")+ , (LANGUAGE_IBIBIO, "LANGUAGE_IBIBIO")+ , (LANGUAGE_ICELANDIC, "LANGUAGE_ICELANDIC")+ , (LANGUAGE_IDO, "LANGUAGE_IDO")+ , (LANGUAGE_IGBO, "LANGUAGE_IGBO")+ , (LANGUAGE_IJO, "LANGUAGE_IJO")+ , (LANGUAGE_ILOKANO, "LANGUAGE_ILOKANO")+ , (LANGUAGE_INARI_SAMI, "LANGUAGE_INARI_SAMI")+ , (LANGUAGE_INDONESIAN, "LANGUAGE_INDONESIAN")+ , (LANGUAGE_INGUSH, "LANGUAGE_INGUSH")+ , (LANGUAGE_INTERLINGUA, "LANGUAGE_INTERLINGUA")+ , (LANGUAGE_INTERLINGUE, "LANGUAGE_INTERLINGUE")+ , (LANGUAGE_INUKTITUT, "LANGUAGE_INUKTITUT")+ , (LANGUAGE_INUPIAT, "LANGUAGE_INUPIAT")+ , (LANGUAGE_IPA_PHONETIC, "LANGUAGE_IPA_PHONETIC")+ , (LANGUAGE_IRISH, "LANGUAGE_IRISH")+ , (LANGUAGE_IRISH_TRADITIONAL, "LANGUAGE_IRISH_TRADITIONAL")+ , (LANGUAGE_IRULA, "LANGUAGE_IRULA")+ , (LANGUAGE_ITALIAN, "LANGUAGE_ITALIAN")+ , (LANGUAGE_JAMAICAN_CREOLE, "LANGUAGE_JAMAICAN_CREOLE")+ , (LANGUAGE_JAPANESE, "LANGUAGE_JAPANESE")+ , (LANGUAGE_JAVANESE, "LANGUAGE_JAVANESE")+ , (LANGUAGE_JENNU_KURUMA, "LANGUAGE_JENNU_KURUMA")+ , (LANGUAGE_JUDEO_TAT, "LANGUAGE_JUDEO_TAT")+ , (LANGUAGE_JULA, "LANGUAGE_JULA")+ , (LANGUAGE_KABARDIAN, "LANGUAGE_KABARDIAN")+ , (LANGUAGE_KABYLE, "LANGUAGE_KABYLE")+ , (LANGUAGE_KACHCHI, "LANGUAGE_KACHCHI")+ , (LANGUAGE_KADIWEU, "LANGUAGE_KADIWEU")+ , (LANGUAGE_KALENJIN, "LANGUAGE_KALENJIN")+ , (LANGUAGE_KALMYK, "LANGUAGE_KALMYK")+ , (LANGUAGE_KAMBA, "LANGUAGE_KAMBA")+ , (LANGUAGE_KANAUJI, "LANGUAGE_KANAUJI")+ , (LANGUAGE_KANNADA, "LANGUAGE_KANNADA")+ , (LANGUAGE_KANURI, "LANGUAGE_KANURI")+ , (LANGUAGE_KAQCHIKEL, "LANGUAGE_KAQCHIKEL")+ , (LANGUAGE_KARACHAY, "LANGUAGE_KARACHAY")+ , (LANGUAGE_KARAIM, "LANGUAGE_KARAIM")+ , (LANGUAGE_KARAKALPAK, "LANGUAGE_KARAKALPAK")+ , (LANGUAGE_KARELIAN, "LANGUAGE_KARELIAN")+ , (LANGUAGE_KAREN, "LANGUAGE_KAREN")+ , (LANGUAGE_KASHMIRI, "LANGUAGE_KASHMIRI")+ , (LANGUAGE_KASHUBIAN, "LANGUAGE_KASHUBIAN")+ , (LANGUAGE_KATE, "LANGUAGE_KATE")+ , (LANGUAGE_KAZAKH, "LANGUAGE_KAZAKH")+ , (LANGUAGE_KEBENA, "LANGUAGE_KEBENA")+ , (LANGUAGE_KEKCHI, "LANGUAGE_KEKCHI")+ , (LANGUAGE_KHAKASS, "LANGUAGE_KHAKASS")+ , (LANGUAGE_KHAMTI_SHAN, "LANGUAGE_KHAMTI_SHAN")+ , (LANGUAGE_KHAMYANG, "LANGUAGE_KHAMYANG")+ , (LANGUAGE_KHANTY_KAZIM, "LANGUAGE_KHANTY_KAZIM")+ , (LANGUAGE_KHANTY_SHURISHKAR, "LANGUAGE_KHANTY_SHURISHKAR")+ , (LANGUAGE_KHANTY_VAKHI, "LANGUAGE_KHANTY_VAKHI")+ , (LANGUAGE_KHASI, "LANGUAGE_KHASI")+ , (LANGUAGE_KHENGKHA, "LANGUAGE_KHENGKHA")+ , (LANGUAGE_KHINALUG, "LANGUAGE_KHINALUG")+ , (LANGUAGE_KHMER, "LANGUAGE_KHMER")+ , (LANGUAGE_KHORASANI_TURKIC, "LANGUAGE_KHORASANI_TURKIC")+ , (LANGUAGE_KHOWAR, "LANGUAGE_KHOWAR")+ , (LANGUAGE_KHUTSURI_GEORGIAN, "LANGUAGE_KHUTSURI_GEORGIAN")+ , (LANGUAGE_KICHE, "LANGUAGE_KICHE")+ , (LANGUAGE_KIKONGO, "LANGUAGE_KIKONGO")+ , (LANGUAGE_KILDIN_SAMI, "LANGUAGE_KILDIN_SAMI")+ , (LANGUAGE_KINYARWANDA, "LANGUAGE_KINYARWANDA")+ , (LANGUAGE_KIRMANJKI, "LANGUAGE_KIRMANJKI")+ , (LANGUAGE_KISII, "LANGUAGE_KISII")+ , (LANGUAGE_KITUBA, "LANGUAGE_KITUBA")+ , (LANGUAGE_KODAGU, "LANGUAGE_KODAGU")+ , (LANGUAGE_KOKNI, "LANGUAGE_KOKNI")+ , (LANGUAGE_KOMI, "LANGUAGE_KOMI")+ , (LANGUAGE_KOMI_PERMYAK, "LANGUAGE_KOMI_PERMYAK")+ , (LANGUAGE_KOMI_ZYRIAN, "LANGUAGE_KOMI_ZYRIAN")+ , (LANGUAGE_KOMO, "LANGUAGE_KOMO")+ , (LANGUAGE_KOMSO, "LANGUAGE_KOMSO")+ , (LANGUAGE_KONGO, "LANGUAGE_KONGO")+ , (LANGUAGE_KONKANI, "LANGUAGE_KONKANI")+ , (LANGUAGE_KOORETE, "LANGUAGE_KOORETE")+ , (LANGUAGE_KOREAN, "LANGUAGE_KOREAN")+ , (LANGUAGE_KOREAO_OLD_HANGUL, "LANGUAGE_KOREAO_OLD_HANGUL")+ , (LANGUAGE_KORYAK, "LANGUAGE_KORYAK")+ , (LANGUAGE_KOSRAEAN, "LANGUAGE_KOSRAEAN")+ , (LANGUAGE_KPELLE, "LANGUAGE_KPELLE")+ , (LANGUAGE_KPELLE_LIBERIA, "LANGUAGE_KPELLE_LIBERIA")+ , (LANGUAGE_KRIO, "LANGUAGE_KRIO")+ , (LANGUAGE_KRYMCHAK, "LANGUAGE_KRYMCHAK")+ , (LANGUAGE_KUANYAMA, "LANGUAGE_KUANYAMA")+ , (LANGUAGE_KUBE, "LANGUAGE_KUBE")+ , (LANGUAGE_KUI, "LANGUAGE_KUI")+ , (LANGUAGE_KULVI, "LANGUAGE_KULVI")+ , (LANGUAGE_KUMAONI, "LANGUAGE_KUMAONI")+ , (LANGUAGE_KUMYK, "LANGUAGE_KUMYK")+ , (LANGUAGE_KURDISH, "LANGUAGE_KURDISH")+ , (LANGUAGE_KURUKH, "LANGUAGE_KURUKH")+ , (LANGUAGE_KUY, "LANGUAGE_KUY")+ , (LANGUAGE_KWAKWALA, "LANGUAGE_KWAKWALA")+ , (LANGUAGE_KYRGYZ, "LANGUAGE_KYRGYZ")+ , (LANGUAGE_L_CREE, "LANGUAGE_L_CREE")+ , (LANGUAGE_LADAKHI, "LANGUAGE_LADAKHI")+ , (LANGUAGE_LADIN, "LANGUAGE_LADIN")+ , (LANGUAGE_LADINO, "LANGUAGE_LADINO")+ , (LANGUAGE_LAHULI, "LANGUAGE_LAHULI")+ , (LANGUAGE_LAK, "LANGUAGE_LAK")+ , (LANGUAGE_LAKI, "LANGUAGE_LAKI")+ , (LANGUAGE_LAMBANI, "LANGUAGE_LAMBANI")+ , (LANGUAGE_LAMPUNG, "LANGUAGE_LAMPUNG")+ , (LANGUAGE_LAO, "LANGUAGE_LAO")+ , (LANGUAGE_LATIN, "LANGUAGE_LATIN")+ , (LANGUAGE_LATVIAN, "LANGUAGE_LATVIAN")+ , (LANGUAGE_LAZ, "LANGUAGE_LAZ")+ , (LANGUAGE_LELEMI, "LANGUAGE_LELEMI")+ , (LANGUAGE_LEZGI, "LANGUAGE_LEZGI")+ , (LANGUAGE_LIGURIAN, "LANGUAGE_LIGURIAN")+ , (LANGUAGE_LIMBU, "LANGUAGE_LIMBU")+ , (LANGUAGE_LIMBURGISH, "LANGUAGE_LIMBURGISH")+ , (LANGUAGE_LINGALA, "LANGUAGE_LINGALA")+ , (LANGUAGE_LIPO, "LANGUAGE_LIPO")+ , (LANGUAGE_LISU, "LANGUAGE_LISU")+ , (LANGUAGE_LITHUANIAN, "LANGUAGE_LITHUANIAN")+ , (LANGUAGE_LIV, "LANGUAGE_LIV")+ , (LANGUAGE_LOJBAN, "LANGUAGE_LOJBAN")+ , (LANGUAGE_LOMA, "LANGUAGE_LOMA")+ , (LANGUAGE_LOMBARD, "LANGUAGE_LOMBARD")+ , (LANGUAGE_LOMWE, "LANGUAGE_LOMWE")+ , (LANGUAGE_LOW_MARI, "LANGUAGE_LOW_MARI")+ , (LANGUAGE_LOW_SAXON, "LANGUAGE_LOW_SAXON")+ , (LANGUAGE_LOWER_SORBIAN, "LANGUAGE_LOWER_SORBIAN")+ , (LANGUAGE_LU, "LANGUAGE_LU")+ , (LANGUAGE_LUBA_KATANGA, "LANGUAGE_LUBA_KATANGA")+ , (LANGUAGE_LUBA_LULUA, "LANGUAGE_LUBA_LULUA")+ , (LANGUAGE_LULE_SAMI, "LANGUAGE_LULE_SAMI")+ , (LANGUAGE_LUO, "LANGUAGE_LUO")+ , (LANGUAGE_LURI, "LANGUAGE_LURI")+ , (LANGUAGE_LUSHOOTSEED, "LANGUAGE_LUSHOOTSEED")+ , (LANGUAGE_LUXEMBOURGISH, "LANGUAGE_LUXEMBOURGISH")+ , (LANGUAGE_LUYIA, "LANGUAGE_LUYIA")+ , (LANGUAGE_MACEDONIAN, "LANGUAGE_MACEDONIAN")+ , (LANGUAGE_MADURA, "LANGUAGE_MADURA")+ , (LANGUAGE_MAGAHI, "LANGUAGE_MAGAHI")+ , (LANGUAGE_MAITHILI, "LANGUAGE_MAITHILI")+ , (LANGUAGE_MAJANG, "LANGUAGE_MAJANG")+ , (LANGUAGE_MAKASAR, "LANGUAGE_MAKASAR")+ , (LANGUAGE_MAKHUWA, "LANGUAGE_MAKHUWA")+ , (LANGUAGE_MAKONDE, "LANGUAGE_MAKONDE")+ , (LANGUAGE_MALAGASY, "LANGUAGE_MALAGASY")+ , (LANGUAGE_MALAY, "LANGUAGE_MALAY")+ , (LANGUAGE_MALAYALAM, "LANGUAGE_MALAYALAM")+ , (LANGUAGE_MALAYALAM_REFORMED, "LANGUAGE_MALAYALAM_REFORMED")+ , (LANGUAGE_MALE, "LANGUAGE_MALE")+ , (LANGUAGE_MALINKE, "LANGUAGE_MALINKE")+ , (LANGUAGE_MALTESE, "LANGUAGE_MALTESE")+ , (LANGUAGE_MAM, "LANGUAGE_MAM")+ , (LANGUAGE_MANCHU, "LANGUAGE_MANCHU")+ , (LANGUAGE_MANDAR, "LANGUAGE_MANDAR")+ , (LANGUAGE_MANDINKA, "LANGUAGE_MANDINKA")+ , (LANGUAGE_MANINKA, "LANGUAGE_MANINKA")+ , (LANGUAGE_MANIPURI, "LANGUAGE_MANIPURI")+ , (LANGUAGE_MANO, "LANGUAGE_MANO")+ , (LANGUAGE_MANSI, "LANGUAGE_MANSI")+ , (LANGUAGE_MANX, "LANGUAGE_MANX")+ , (LANGUAGE_MAORI, "LANGUAGE_MAORI")+ , (LANGUAGE_MAPUDUNGUN, "LANGUAGE_MAPUDUNGUN")+ , (LANGUAGE_MARATHI, "LANGUAGE_MARATHI")+ , (LANGUAGE_MARSHALLESE, "LANGUAGE_MARSHALLESE")+ , (LANGUAGE_MARWARI, "LANGUAGE_MARWARI")+ , (LANGUAGE_MAYAN, "LANGUAGE_MAYAN")+ , (LANGUAGE_MAZANDERANI, "LANGUAGE_MAZANDERANI")+ , (LANGUAGE_MBEMBE_TIGON, "LANGUAGE_MBEMBE_TIGON")+ , (LANGUAGE_MBO, "LANGUAGE_MBO")+ , (LANGUAGE_MBUNDU, "LANGUAGE_MBUNDU")+ , (LANGUAGE_MEDUMBA, "LANGUAGE_MEDUMBA")+ , (LANGUAGE_MEEN, "LANGUAGE_MEEN")+ , (LANGUAGE_MENDE, "LANGUAGE_MENDE")+ , (LANGUAGE_MERU, "LANGUAGE_MERU")+ , (LANGUAGE_MEWATI, "LANGUAGE_MEWATI")+ , (LANGUAGE_MINANGKABAU, "LANGUAGE_MINANGKABAU")+ , (LANGUAGE_MINJANGBAL, "LANGUAGE_MINJANGBAL")+ , (LANGUAGE_MIRANDESE, "LANGUAGE_MIRANDESE")+ , (LANGUAGE_MIZO, "LANGUAGE_MIZO")+ , (LANGUAGE_MOHAWK, "LANGUAGE_MOHAWK")+ , (LANGUAGE_MOKSHA, "LANGUAGE_MOKSHA")+ , (LANGUAGE_MOLDAVIAN, "LANGUAGE_MOLDAVIAN")+ , (LANGUAGE_MON, "LANGUAGE_MON")+ , (LANGUAGE_MONGOLIAN, "LANGUAGE_MONGOLIAN")+ , (LANGUAGE_MOOSE_CREE, "LANGUAGE_MOOSE_CREE")+ , (LANGUAGE_MORISYEN, "LANGUAGE_MORISYEN")+ , (LANGUAGE_MOROCCAN, "LANGUAGE_MOROCCAN")+ , (LANGUAGE_MOSSI, "LANGUAGE_MOSSI")+ , (LANGUAGE_MUNDARI, "LANGUAGE_MUNDARI")+ , (LANGUAGE_MUSCOGEE, "LANGUAGE_MUSCOGEE")+ , (LANGUAGE_N_CREE, "LANGUAGE_N_CREE")+ , (LANGUAGE_NAGA_ASSAMESE, "LANGUAGE_NAGA_ASSAMESE")+ , (LANGUAGE_NAGARI, "LANGUAGE_NAGARI")+ , (LANGUAGE_NAHUATL, "LANGUAGE_NAHUATL")+ , (LANGUAGE_NANAI, "LANGUAGE_NANAI")+ , (LANGUAGE_NASKAPI, "LANGUAGE_NASKAPI")+ , (LANGUAGE_NAURUAN, "LANGUAGE_NAURUAN")+ , (LANGUAGE_NAVAJO, "LANGUAGE_NAVAJO")+ , (LANGUAGE_NDAU, "LANGUAGE_NDAU")+ , (LANGUAGE_NDEBELE, "LANGUAGE_NDEBELE")+ , (LANGUAGE_NDONGA, "LANGUAGE_NDONGA")+ , (LANGUAGE_NEAPOLITAN, "LANGUAGE_NEAPOLITAN")+ , (LANGUAGE_NEPALI, "LANGUAGE_NEPALI")+ , (LANGUAGE_NEWARI, "LANGUAGE_NEWARI")+ , (LANGUAGE_NGBAKA, "LANGUAGE_NGBAKA")+ , (LANGUAGE_NIGERIAN_FULFULDE, "LANGUAGE_NIGERIAN_FULFULDE")+ , (LANGUAGE_NIMADI, "LANGUAGE_NIMADI")+ , (LANGUAGE_NISI, "LANGUAGE_NISI")+ , (LANGUAGE_NIUEAN, "LANGUAGE_NIUEAN")+ , (LANGUAGE_NKO, "LANGUAGE_NKO")+ , (LANGUAGE_NOGAI, "LANGUAGE_NOGAI")+ , (LANGUAGE_NORFOLK, "LANGUAGE_NORFOLK")+ , (LANGUAGE_NORTH_SLAVEY, "LANGUAGE_NORTH_SLAVEY")+ , (LANGUAGE_NORTHERN_EMBERA, "LANGUAGE_NORTHERN_EMBERA")+ , (LANGUAGE_NORTHERN_SAMI, "LANGUAGE_NORTHERN_SAMI")+ , (LANGUAGE_NORTHERN_SOTHO, "LANGUAGE_NORTHERN_SOTHO")+ , (LANGUAGE_NORTHERN_TAI, "LANGUAGE_NORTHERN_TAI")+ , (LANGUAGE_NORWAY_HOUSE_CREE, "LANGUAGE_NORWAY_HOUSE_CREE")+ , (LANGUAGE_NORWEGIAN, "LANGUAGE_NORWEGIAN")+ , (LANGUAGE_NORWEGIAN_NYNORSK, "LANGUAGE_NORWEGIAN_NYNORSK")+ , (LANGUAGE_NOVIAL, "LANGUAGE_NOVIAL")+ , (LANGUAGE_NUMANGGANG, "LANGUAGE_NUMANGGANG")+ , (LANGUAGE_NUNAVIK_INUKTITUT, "LANGUAGE_NUNAVIK_INUKTITUT")+ , (LANGUAGE_NUU_CHAH_NULTH, "LANGUAGE_NUU_CHAH_NULTH")+ , (LANGUAGE_NYAMWEZI, "LANGUAGE_NYAMWEZI")+ , (LANGUAGE_NYANKOLE, "LANGUAGE_NYANKOLE")+ , (LANGUAGE_OCCITAN, "LANGUAGE_OCCITAN")+ , (LANGUAGE_ODIA, "LANGUAGE_ODIA")+ , (LANGUAGE_OJI_CREE, "LANGUAGE_OJI_CREE")+ , (LANGUAGE_OJIBWAY, "LANGUAGE_OJIBWAY")+ , (LANGUAGE_OLD_IRISH, "LANGUAGE_OLD_IRISH")+ , (LANGUAGE_OLD_JAVANESE, "LANGUAGE_OLD_JAVANESE")+ , (LANGUAGE_ONEIDA, "LANGUAGE_ONEIDA")+ , (LANGUAGE_ONONDAGA, "LANGUAGE_ONONDAGA")+ , (LANGUAGE_OROMO, "LANGUAGE_OROMO")+ , (LANGUAGE_OSSETIAN, "LANGUAGE_OSSETIAN")+ , (LANGUAGE_PA_O_KAREN, "LANGUAGE_PA_O_KAREN")+ , (LANGUAGE_PALAUAN, "LANGUAGE_PALAUAN")+ , (LANGUAGE_PALAUNG, "LANGUAGE_PALAUNG")+ , (LANGUAGE_PALESTINIAN_ARAMAIC, "LANGUAGE_PALESTINIAN_ARAMAIC")+ , (LANGUAGE_PALI, "LANGUAGE_PALI")+ , (LANGUAGE_PALPA, "LANGUAGE_PALPA")+ , (LANGUAGE_PAMPANGAN, "LANGUAGE_PAMPANGAN")+ , (LANGUAGE_PANGASINAN, "LANGUAGE_PANGASINAN")+ , (LANGUAGE_PAPIAMENTU, "LANGUAGE_PAPIAMENTU")+ , (LANGUAGE_PASHTO, "LANGUAGE_PASHTO")+ , (LANGUAGE_PATTANI_MALAY, "LANGUAGE_PATTANI_MALAY")+ , (LANGUAGE_PENNSYLVANIA_GERMAN, "LANGUAGE_PENNSYLVANIA_GERMAN")+ , (LANGUAGE_PERSIAN, "LANGUAGE_PERSIAN")+ , (LANGUAGE_PHAKE, "LANGUAGE_PHAKE")+ , (LANGUAGE_PICARD, "LANGUAGE_PICARD")+ , (LANGUAGE_PIEMONTESE, "LANGUAGE_PIEMONTESE")+ , (LANGUAGE_PILAGA, "LANGUAGE_PILAGA")+ , (LANGUAGE_PITE_SAMI, "LANGUAGE_PITE_SAMI")+ , (LANGUAGE_POCOMCHI, "LANGUAGE_POCOMCHI")+ , (LANGUAGE_POHNPEIAN, "LANGUAGE_POHNPEIAN")+ , (LANGUAGE_POLISH, "LANGUAGE_POLISH")+ , (LANGUAGE_POLYTONIC_GREEK, "LANGUAGE_POLYTONIC_GREEK")+ , (LANGUAGE_PORTUGUESE, "LANGUAGE_PORTUGUESE")+ , (LANGUAGE_PROVENCAL, "LANGUAGE_PROVENCAL")+ , (LANGUAGE_PUNJABI, "LANGUAGE_PUNJABI")+ , (LANGUAGE_QUECHUA, "LANGUAGE_QUECHUA")+ , (LANGUAGE_QUECHUA_BOLIVIA, "LANGUAGE_QUECHUA_BOLIVIA")+ , (LANGUAGE_QUECHUA_ECUADOR, "LANGUAGE_QUECHUA_ECUADOR")+ , (LANGUAGE_QUECHUA_PERU, "LANGUAGE_QUECHUA_PERU")+ , (LANGUAGE_R_CREE, "LANGUAGE_R_CREE")+ , (LANGUAGE_RAJASTHANI, "LANGUAGE_RAJASTHANI")+ , (LANGUAGE_RAKHINE, "LANGUAGE_RAKHINE")+ , (LANGUAGE_RAROTONGAN, "LANGUAGE_RAROTONGAN")+ , (LANGUAGE_REJANG, "LANGUAGE_REJANG")+ , (LANGUAGE_RIANG, "LANGUAGE_RIANG")+ , (LANGUAGE_RIPUARIAN, "LANGUAGE_RIPUARIAN")+ , (LANGUAGE_RITARUNGO, "LANGUAGE_RITARUNGO")+ , (LANGUAGE_ROHINGYA, "LANGUAGE_ROHINGYA")+ , (LANGUAGE_ROMANIAN, "LANGUAGE_ROMANIAN")+ , (LANGUAGE_ROMANSH, "LANGUAGE_ROMANSH")+ , (LANGUAGE_ROMANY, "LANGUAGE_ROMANY")+ , (LANGUAGE_ROTUMAN, "LANGUAGE_ROTUMAN")+ , (LANGUAGE_RUNDI, "LANGUAGE_RUNDI")+ , (LANGUAGE_RUSSIAN, "LANGUAGE_RUSSIAN")+ , (LANGUAGE_RUSSIAN_BURIAT, "LANGUAGE_RUSSIAN_BURIAT")+ , (LANGUAGE_RUSYN, "LANGUAGE_RUSYN")+ , (LANGUAGE_SADRI, "LANGUAGE_SADRI")+ , (LANGUAGE_SAKHA, "LANGUAGE_SAKHA")+ , (LANGUAGE_SAMOAN, "LANGUAGE_SAMOAN")+ , (LANGUAGE_SAMOGITIAN, "LANGUAGE_SAMOGITIAN")+ , (LANGUAGE_SAN_BLAS_KUNA, "LANGUAGE_SAN_BLAS_KUNA")+ , (LANGUAGE_SANGO, "LANGUAGE_SANGO")+ , (LANGUAGE_SANSKRIT, "LANGUAGE_SANSKRIT")+ , (LANGUAGE_SANTALI, "LANGUAGE_SANTALI")+ , (LANGUAGE_SARAIKI, "LANGUAGE_SARAIKI")+ , (LANGUAGE_SARDINIAN, "LANGUAGE_SARDINIAN")+ , (LANGUAGE_SASAK, "LANGUAGE_SASAK")+ , (LANGUAGE_SATERLAND_FRISIAN, "LANGUAGE_SATERLAND_FRISIAN")+ , (LANGUAGE_SAYISI, "LANGUAGE_SAYISI")+ , (LANGUAGE_SCOTS, "LANGUAGE_SCOTS")+ , (LANGUAGE_SCOTTISH_GAELIC, "LANGUAGE_SCOTTISH_GAELIC")+ , (LANGUAGE_SEKOTA, "LANGUAGE_SEKOTA")+ , (LANGUAGE_SELKUP, "LANGUAGE_SELKUP")+ , (LANGUAGE_SENA, "LANGUAGE_SENA")+ , (LANGUAGE_SENECA, "LANGUAGE_SENECA")+ , (LANGUAGE_SERBIAN, "LANGUAGE_SERBIAN")+ , (LANGUAGE_SERER, "LANGUAGE_SERER")+ , (LANGUAGE_SGAW_KAREN, "LANGUAGE_SGAW_KAREN")+ , (LANGUAGE_SHAN, "LANGUAGE_SHAN")+ , (LANGUAGE_SHONA, "LANGUAGE_SHONA")+ , (LANGUAGE_SIBE, "LANGUAGE_SIBE")+ , (LANGUAGE_SICILIAN, "LANGUAGE_SICILIAN")+ , (LANGUAGE_SIDAMO, "LANGUAGE_SIDAMO")+ , (LANGUAGE_SILESIAN, "LANGUAGE_SILESIAN")+ , (LANGUAGE_SILTE_GURAGE, "LANGUAGE_SILTE_GURAGE")+ , (LANGUAGE_SINDHI, "LANGUAGE_SINDHI")+ , (LANGUAGE_SINHALA, "LANGUAGE_SINHALA")+ , (LANGUAGE_SKOLT_SAMI, "LANGUAGE_SKOLT_SAMI")+ , (LANGUAGE_SLAVEY, "LANGUAGE_SLAVEY")+ , (LANGUAGE_SLOVAK, "LANGUAGE_SLOVAK")+ , (LANGUAGE_SLOVENIAN, "LANGUAGE_SLOVENIAN")+ , (LANGUAGE_SMALL_FLOWERY_MIAO, "LANGUAGE_SMALL_FLOWERY_MIAO")+ , (LANGUAGE_SODO_GURAGE, "LANGUAGE_SODO_GURAGE")+ , (LANGUAGE_SOGA, "LANGUAGE_SOGA")+ , (LANGUAGE_SOMALI, "LANGUAGE_SOMALI")+ , (LANGUAGE_SONGE, "LANGUAGE_SONGE")+ , (LANGUAGE_SONINKE, "LANGUAGE_SONINKE")+ , (LANGUAGE_SOUTH_SLAVEY, "LANGUAGE_SOUTH_SLAVEY")+ , (LANGUAGE_SOUTHERN_KIWAI, "LANGUAGE_SOUTHERN_KIWAI")+ , (LANGUAGE_SOUTHERN_SAMI, "LANGUAGE_SOUTHERN_SAMI")+ , (LANGUAGE_SOUTHERN_SOTHO, "LANGUAGE_SOUTHERN_SOTHO")+ , (LANGUAGE_SPANISH, "LANGUAGE_SPANISH")+ , (LANGUAGE_STANDARD_MOROCCAN_TAMAZIGHT, "LANGUAGE_STANDARD_MOROCCAN_TAMAZIGHT")+ , (LANGUAGE_STRAITS_SALISH, "LANGUAGE_STRAITS_SALISH")+ , (LANGUAGE_SUKUMA, "LANGUAGE_SUKUMA")+ , (LANGUAGE_SUNDANESE, "LANGUAGE_SUNDANESE")+ , (LANGUAGE_SURI, "LANGUAGE_SURI")+ , (LANGUAGE_SUTU, "LANGUAGE_SUTU")+ , (LANGUAGE_SVAN, "LANGUAGE_SVAN")+ , (LANGUAGE_SWADAYA_ARAMAIC, "LANGUAGE_SWADAYA_ARAMAIC")+ , (LANGUAGE_SWAHILI, "LANGUAGE_SWAHILI")+ , (LANGUAGE_SWATI, "LANGUAGE_SWATI")+ , (LANGUAGE_SWEDISH, "LANGUAGE_SWEDISH")+ , (LANGUAGE_SYLHETI, "LANGUAGE_SYLHETI")+ , (LANGUAGE_SYRIAC, "LANGUAGE_SYRIAC")+ , (LANGUAGE_SYRIAC_EASTERN, "LANGUAGE_SYRIAC_EASTERN")+ , (LANGUAGE_SYRIAC_ESTRANGELA, "LANGUAGE_SYRIAC_ESTRANGELA")+ , (LANGUAGE_SYRIAC_WESTERN, "LANGUAGE_SYRIAC_WESTERN")+ , (LANGUAGE_TABASARAN, "LANGUAGE_TABASARAN")+ , (LANGUAGE_TACHELHIT, "LANGUAGE_TACHELHIT")+ , (LANGUAGE_TAGALOG, "LANGUAGE_TAGALOG")+ , (LANGUAGE_TAHAGGART_TAMAHAQ, "LANGUAGE_TAHAGGART_TAMAHAQ")+ , (LANGUAGE_TAHITIAN, "LANGUAGE_TAHITIAN")+ , (LANGUAGE_TAI_LAING, "LANGUAGE_TAI_LAING")+ , (LANGUAGE_TAJIKI, "LANGUAGE_TAJIKI")+ , (LANGUAGE_TALYSH, "LANGUAGE_TALYSH")+ , (LANGUAGE_TAMASHEK, "LANGUAGE_TAMASHEK")+ , (LANGUAGE_TAMASHEQ, "LANGUAGE_TAMASHEQ")+ , (LANGUAGE_TAMAZIGHT, "LANGUAGE_TAMAZIGHT")+ , (LANGUAGE_TAMIL, "LANGUAGE_TAMIL")+ , (LANGUAGE_TARIFIT, "LANGUAGE_TARIFIT")+ , (LANGUAGE_TATAR, "LANGUAGE_TATAR")+ , (LANGUAGE_TAWALLAMMAT_TAMAJAQ, "LANGUAGE_TAWALLAMMAT_TAMAJAQ")+ , (LANGUAGE_TAY, "LANGUAGE_TAY")+ , (LANGUAGE_TAYART_TAMAJEQ, "LANGUAGE_TAYART_TAMAJEQ")+ , (LANGUAGE_TELUGU, "LANGUAGE_TELUGU")+ , (LANGUAGE_TEMNE, "LANGUAGE_TEMNE")+ , (LANGUAGE_TETUM, "LANGUAGE_TETUM")+ , (LANGUAGE_TH_CREE, "LANGUAGE_TH_CREE")+ , (LANGUAGE_THAI, "LANGUAGE_THAI")+ , (LANGUAGE_THAILAND_MON, "LANGUAGE_THAILAND_MON")+ , (LANGUAGE_THOMPSON, "LANGUAGE_THOMPSON")+ , (LANGUAGE_TIBETAN, "LANGUAGE_TIBETAN")+ , (LANGUAGE_TIGRE, "LANGUAGE_TIGRE")+ , (LANGUAGE_TIGRINYA, "LANGUAGE_TIGRINYA")+ , (LANGUAGE_TIV, "LANGUAGE_TIV")+ , (LANGUAGE_TLINGIT, "LANGUAGE_TLINGIT")+ , (LANGUAGE_TOBO, "LANGUAGE_TOBO")+ , (LANGUAGE_TODO, "LANGUAGE_TODO")+ , (LANGUAGE_TOK_PISIN, "LANGUAGE_TOK_PISIN")+ , (LANGUAGE_TOMA, "LANGUAGE_TOMA")+ , (LANGUAGE_TONGA, "LANGUAGE_TONGA")+ , (LANGUAGE_TONGAN, "LANGUAGE_TONGAN")+ , (LANGUAGE_TORKI, "LANGUAGE_TORKI")+ , (LANGUAGE_TSHANGLA, "LANGUAGE_TSHANGLA")+ , (LANGUAGE_TSONGA, "LANGUAGE_TSONGA")+ , (LANGUAGE_TSWANA, "LANGUAGE_TSWANA")+ , (LANGUAGE_TULU, "LANGUAGE_TULU")+ , (LANGUAGE_TUMBUKA, "LANGUAGE_TUMBUKA")+ , (LANGUAGE_TUNDRA_ENETS, "LANGUAGE_TUNDRA_ENETS")+ , (LANGUAGE_TURKISH, "LANGUAGE_TURKISH")+ , (LANGUAGE_TURKMEN, "LANGUAGE_TURKMEN")+ , (LANGUAGE_TUROYO_ARAMAIC, "LANGUAGE_TUROYO_ARAMAIC")+ , (LANGUAGE_TUSCARORA, "LANGUAGE_TUSCARORA")+ , (LANGUAGE_TUVALU, "LANGUAGE_TUVALU")+ , (LANGUAGE_TUVIN, "LANGUAGE_TUVIN")+ , (LANGUAGE_TWI, "LANGUAGE_TWI")+ , (LANGUAGE_TZOTZIL, "LANGUAGE_TZOTZIL")+ , (LANGUAGE_UDI, "LANGUAGE_UDI")+ , (LANGUAGE_UDMURT, "LANGUAGE_UDMURT")+ , (LANGUAGE_UKRAINIAN, "LANGUAGE_UKRAINIAN")+ , (LANGUAGE_UMBUNDU, "LANGUAGE_UMBUNDU")+ , (LANGUAGE_UME_SAMI, "LANGUAGE_UME_SAMI")+ , (LANGUAGE_UPPER_SAXON, "LANGUAGE_UPPER_SAXON")+ , (LANGUAGE_UPPER_SORBIAN, "LANGUAGE_UPPER_SORBIAN")+ , (LANGUAGE_URALIC_PHONETIC, "LANGUAGE_URALIC_PHONETIC")+ , (LANGUAGE_URDU, "LANGUAGE_URDU")+ , (LANGUAGE_UYGHUR, "LANGUAGE_UYGHUR")+ , (LANGUAGE_UZBEK, "LANGUAGE_UZBEK")+ , (LANGUAGE_VENDA, "LANGUAGE_VENDA")+ , (LANGUAGE_VENETIAN, "LANGUAGE_VENETIAN")+ , (LANGUAGE_VIETNAMESE, "LANGUAGE_VIETNAMESE")+ , (LANGUAGE_VLAX_ROMANI, "LANGUAGE_VLAX_ROMANI")+ , (LANGUAGE_VOLAPUK, "LANGUAGE_VOLAPUK")+ , (LANGUAGE_VORO, "LANGUAGE_VORO")+ , (LANGUAGE_WA, "LANGUAGE_WA")+ , (LANGUAGE_WACI_GBE, "LANGUAGE_WACI_GBE")+ , (LANGUAGE_WAGDI, "LANGUAGE_WAGDI")+ , (LANGUAGE_WAKHI, "LANGUAGE_WAKHI")+ , (LANGUAGE_WALLOON, "LANGUAGE_WALLOON")+ , (LANGUAGE_WARAY_WARAY, "LANGUAGE_WARAY_WARAY")+ , (LANGUAGE_WAYANAD_CHETTI, "LANGUAGE_WAYANAD_CHETTI")+ , (LANGUAGE_WAYUU, "LANGUAGE_WAYUU")+ , (LANGUAGE_WELSH, "LANGUAGE_WELSH")+ , (LANGUAGE_WENDAT, "LANGUAGE_WENDAT")+ , (LANGUAGE_WEST_CREE, "LANGUAGE_WEST_CREE")+ , (LANGUAGE_WESTERN_CHAM, "LANGUAGE_WESTERN_CHAM")+ , (LANGUAGE_WESTERN_KAYAH, "LANGUAGE_WESTERN_KAYAH")+ , (LANGUAGE_WESTERN_PANJABI, "LANGUAGE_WESTERN_PANJABI")+ , (LANGUAGE_WESTERN_PWO_KAREN, "LANGUAGE_WESTERN_PWO_KAREN")+ , (LANGUAGE_WOLOF, "LANGUAGE_WOLOF")+ , (LANGUAGE_WOODS_CREE, "LANGUAGE_WOODS_CREE")+ , (LANGUAGE_WUDING_LUQUAN_YI, "LANGUAGE_WUDING_LUQUAN_YI")+ , (LANGUAGE_WYANDOT, "LANGUAGE_WYANDOT")+ , (LANGUAGE_XHOSA, "LANGUAGE_XHOSA")+ , (LANGUAGE_Y_CREE, "LANGUAGE_Y_CREE")+ , (LANGUAGE_YAO, "LANGUAGE_YAO")+ , (LANGUAGE_YAPESE, "LANGUAGE_YAPESE")+ , (LANGUAGE_YI_CLASSIC, "LANGUAGE_YI_CLASSIC")+ , (LANGUAGE_YI_MODERN, "LANGUAGE_YI_MODERN")+ , (LANGUAGE_YIDDISH, "LANGUAGE_YIDDISH")+ , (LANGUAGE_YORUBA, "LANGUAGE_YORUBA")+ , (LANGUAGE_ZAMBOANGA_CHAVACANO, "LANGUAGE_ZAMBOANGA_CHAVACANO")+ , (LANGUAGE_ZANDE, "LANGUAGE_ZANDE")+ , (LANGUAGE_ZARMA, "LANGUAGE_ZARMA")+ , (LANGUAGE_ZAZAKI, "LANGUAGE_ZAZAKI")+ , (LANGUAGE_ZEALANDIC, "LANGUAGE_ZEALANDIC")+ , (LANGUAGE_ZHUANG, "LANGUAGE_ZHUANG")+ , (LANGUAGE_ZULU, "LANGUAGE_ZULU")+ ]
+ src/KB/Text/Shape/FFI/Enums/Script.hsc view
@@ -0,0 +1,703 @@+module KB.Text.Shape.FFI.Enums.Script where++import Prelude hiding (id, error)+import Foreign++import Data.Map (Map)+import Data.Map.Strict qualified as Map++#include "kb_text_shape.h"++newtype Script = Script Word32+ deriving (Eq, Ord)+ deriving newtype (Storable)++instance Show Script where+ showsPrec d s@(Script sv) =+ case Map.lookup s scriptNames of+ Just name -> showString name+ Nothing -> showParen (d > 10) $ showString "Script " . showsPrec 11 sv++pattern SCRIPT_DONT_KNOW :: Script+pattern SCRIPT_DONT_KNOW = Script (#const KBTS_SCRIPT_DONT_KNOW)++pattern SCRIPT_ADLAM :: Script+pattern SCRIPT_ADLAM = Script (#const KBTS_SCRIPT_ADLAM)++pattern SCRIPT_AHOM :: Script+pattern SCRIPT_AHOM = Script (#const KBTS_SCRIPT_AHOM)++pattern SCRIPT_ANATOLIAN_HIEROGLYPHS :: Script+pattern SCRIPT_ANATOLIAN_HIEROGLYPHS = Script (#const KBTS_SCRIPT_ANATOLIAN_HIEROGLYPHS)++pattern SCRIPT_ARABIC :: Script+pattern SCRIPT_ARABIC = Script (#const KBTS_SCRIPT_ARABIC)++pattern SCRIPT_ARMENIAN :: Script+pattern SCRIPT_ARMENIAN = Script (#const KBTS_SCRIPT_ARMENIAN)++pattern SCRIPT_AVESTAN :: Script+pattern SCRIPT_AVESTAN = Script (#const KBTS_SCRIPT_AVESTAN)++pattern SCRIPT_BALINESE :: Script+pattern SCRIPT_BALINESE = Script (#const KBTS_SCRIPT_BALINESE)++pattern SCRIPT_BAMUM :: Script+pattern SCRIPT_BAMUM = Script (#const KBTS_SCRIPT_BAMUM)++pattern SCRIPT_BASSA_VAH :: Script+pattern SCRIPT_BASSA_VAH = Script (#const KBTS_SCRIPT_BASSA_VAH)++pattern SCRIPT_BATAK :: Script+pattern SCRIPT_BATAK = Script (#const KBTS_SCRIPT_BATAK)++pattern SCRIPT_BENGALI :: Script+pattern SCRIPT_BENGALI = Script (#const KBTS_SCRIPT_BENGALI)++pattern SCRIPT_BHAIKSUKI :: Script+pattern SCRIPT_BHAIKSUKI = Script (#const KBTS_SCRIPT_BHAIKSUKI)++pattern SCRIPT_BOPOMOFO :: Script+pattern SCRIPT_BOPOMOFO = Script (#const KBTS_SCRIPT_BOPOMOFO)++pattern SCRIPT_BRAHMI :: Script+pattern SCRIPT_BRAHMI = Script (#const KBTS_SCRIPT_BRAHMI)++pattern SCRIPT_BUGINESE :: Script+pattern SCRIPT_BUGINESE = Script (#const KBTS_SCRIPT_BUGINESE)++pattern SCRIPT_BUHID :: Script+pattern SCRIPT_BUHID = Script (#const KBTS_SCRIPT_BUHID)++pattern SCRIPT_CANADIAN_SYLLABICS :: Script+pattern SCRIPT_CANADIAN_SYLLABICS = Script (#const KBTS_SCRIPT_CANADIAN_SYLLABICS)++pattern SCRIPT_CARIAN :: Script+pattern SCRIPT_CARIAN = Script (#const KBTS_SCRIPT_CARIAN)++pattern SCRIPT_CAUCASIAN_ALBANIAN :: Script+pattern SCRIPT_CAUCASIAN_ALBANIAN = Script (#const KBTS_SCRIPT_CAUCASIAN_ALBANIAN)++pattern SCRIPT_CHAKMA :: Script+pattern SCRIPT_CHAKMA = Script (#const KBTS_SCRIPT_CHAKMA)++pattern SCRIPT_CHAM :: Script+pattern SCRIPT_CHAM = Script (#const KBTS_SCRIPT_CHAM)++pattern SCRIPT_CHEROKEE :: Script+pattern SCRIPT_CHEROKEE = Script (#const KBTS_SCRIPT_CHEROKEE)++pattern SCRIPT_CHORASMIAN :: Script+pattern SCRIPT_CHORASMIAN = Script (#const KBTS_SCRIPT_CHORASMIAN)++pattern SCRIPT_CJK_IDEOGRAPHIC :: Script+pattern SCRIPT_CJK_IDEOGRAPHIC = Script (#const KBTS_SCRIPT_CJK_IDEOGRAPHIC)++pattern SCRIPT_COPTIC :: Script+pattern SCRIPT_COPTIC = Script (#const KBTS_SCRIPT_COPTIC)++pattern SCRIPT_CYPRIOT_SYLLABARY :: Script+pattern SCRIPT_CYPRIOT_SYLLABARY = Script (#const KBTS_SCRIPT_CYPRIOT_SYLLABARY)++pattern SCRIPT_CYPRO_MINOAN :: Script+pattern SCRIPT_CYPRO_MINOAN = Script (#const KBTS_SCRIPT_CYPRO_MINOAN)++pattern SCRIPT_CYRILLIC :: Script+pattern SCRIPT_CYRILLIC = Script (#const KBTS_SCRIPT_CYRILLIC)++pattern SCRIPT_DEFAULT :: Script+pattern SCRIPT_DEFAULT = Script (#const KBTS_SCRIPT_DEFAULT)++pattern SCRIPT_DEFAULT2 :: Script+pattern SCRIPT_DEFAULT2 = Script (#const KBTS_SCRIPT_DEFAULT2)++pattern SCRIPT_DESERET :: Script+pattern SCRIPT_DESERET = Script (#const KBTS_SCRIPT_DESERET)++pattern SCRIPT_DEVANAGARI :: Script+pattern SCRIPT_DEVANAGARI = Script (#const KBTS_SCRIPT_DEVANAGARI)++pattern SCRIPT_DIVES_AKURU :: Script+pattern SCRIPT_DIVES_AKURU = Script (#const KBTS_SCRIPT_DIVES_AKURU)++pattern SCRIPT_DOGRA :: Script+pattern SCRIPT_DOGRA = Script (#const KBTS_SCRIPT_DOGRA)++pattern SCRIPT_DUPLOYAN :: Script+pattern SCRIPT_DUPLOYAN = Script (#const KBTS_SCRIPT_DUPLOYAN)++pattern SCRIPT_EGYPTIAN_HIEROGLYPHS :: Script+pattern SCRIPT_EGYPTIAN_HIEROGLYPHS = Script (#const KBTS_SCRIPT_EGYPTIAN_HIEROGLYPHS)++pattern SCRIPT_ELBASAN :: Script+pattern SCRIPT_ELBASAN = Script (#const KBTS_SCRIPT_ELBASAN)++pattern SCRIPT_ELYMAIC :: Script+pattern SCRIPT_ELYMAIC = Script (#const KBTS_SCRIPT_ELYMAIC)++pattern SCRIPT_ETHIOPIC :: Script+pattern SCRIPT_ETHIOPIC = Script (#const KBTS_SCRIPT_ETHIOPIC)++pattern SCRIPT_GARAY :: Script+pattern SCRIPT_GARAY = Script (#const KBTS_SCRIPT_GARAY)++pattern SCRIPT_GEORGIAN :: Script+pattern SCRIPT_GEORGIAN = Script (#const KBTS_SCRIPT_GEORGIAN)++pattern SCRIPT_GLAGOLITIC :: Script+pattern SCRIPT_GLAGOLITIC = Script (#const KBTS_SCRIPT_GLAGOLITIC)++pattern SCRIPT_GOTHIC :: Script+pattern SCRIPT_GOTHIC = Script (#const KBTS_SCRIPT_GOTHIC)++pattern SCRIPT_GRANTHA :: Script+pattern SCRIPT_GRANTHA = Script (#const KBTS_SCRIPT_GRANTHA)++pattern SCRIPT_GREEK :: Script+pattern SCRIPT_GREEK = Script (#const KBTS_SCRIPT_GREEK)++pattern SCRIPT_GUJARATI :: Script+pattern SCRIPT_GUJARATI = Script (#const KBTS_SCRIPT_GUJARATI)++pattern SCRIPT_GUNJALA_GONDI :: Script+pattern SCRIPT_GUNJALA_GONDI = Script (#const KBTS_SCRIPT_GUNJALA_GONDI)++pattern SCRIPT_GURMUKHI :: Script+pattern SCRIPT_GURMUKHI = Script (#const KBTS_SCRIPT_GURMUKHI)++pattern SCRIPT_GURUNG_KHEMA :: Script+pattern SCRIPT_GURUNG_KHEMA = Script (#const KBTS_SCRIPT_GURUNG_KHEMA)++pattern SCRIPT_HANGUL :: Script+pattern SCRIPT_HANGUL = Script (#const KBTS_SCRIPT_HANGUL)++pattern SCRIPT_HANIFI_ROHINGYA :: Script+pattern SCRIPT_HANIFI_ROHINGYA = Script (#const KBTS_SCRIPT_HANIFI_ROHINGYA)++pattern SCRIPT_HANUNOO :: Script+pattern SCRIPT_HANUNOO = Script (#const KBTS_SCRIPT_HANUNOO)++pattern SCRIPT_HATRAN :: Script+pattern SCRIPT_HATRAN = Script (#const KBTS_SCRIPT_HATRAN)++pattern SCRIPT_HEBREW :: Script+pattern SCRIPT_HEBREW = Script (#const KBTS_SCRIPT_HEBREW)++pattern SCRIPT_HIRAGANA :: Script+pattern SCRIPT_HIRAGANA = Script (#const KBTS_SCRIPT_HIRAGANA)++pattern SCRIPT_IMPERIAL_ARAMAIC :: Script+pattern SCRIPT_IMPERIAL_ARAMAIC = Script (#const KBTS_SCRIPT_IMPERIAL_ARAMAIC)++pattern SCRIPT_INSCRIPTIONAL_PAHLAVI :: Script+pattern SCRIPT_INSCRIPTIONAL_PAHLAVI = Script (#const KBTS_SCRIPT_INSCRIPTIONAL_PAHLAVI)++pattern SCRIPT_INSCRIPTIONAL_PARTHIAN :: Script+pattern SCRIPT_INSCRIPTIONAL_PARTHIAN = Script (#const KBTS_SCRIPT_INSCRIPTIONAL_PARTHIAN)++pattern SCRIPT_JAVANESE :: Script+pattern SCRIPT_JAVANESE = Script (#const KBTS_SCRIPT_JAVANESE)++pattern SCRIPT_KAITHI :: Script+pattern SCRIPT_KAITHI = Script (#const KBTS_SCRIPT_KAITHI)++pattern SCRIPT_KANNADA :: Script+pattern SCRIPT_KANNADA = Script (#const KBTS_SCRIPT_KANNADA)++pattern SCRIPT_KATAKANA :: Script+pattern SCRIPT_KATAKANA = Script (#const KBTS_SCRIPT_KATAKANA)++pattern SCRIPT_KAWI :: Script+pattern SCRIPT_KAWI = Script (#const KBTS_SCRIPT_KAWI)++pattern SCRIPT_KAYAH_LI :: Script+pattern SCRIPT_KAYAH_LI = Script (#const KBTS_SCRIPT_KAYAH_LI)++pattern SCRIPT_KHAROSHTHI :: Script+pattern SCRIPT_KHAROSHTHI = Script (#const KBTS_SCRIPT_KHAROSHTHI)++pattern SCRIPT_KHITAN_SMALL_SCRIPT :: Script+pattern SCRIPT_KHITAN_SMALL_SCRIPT = Script (#const KBTS_SCRIPT_KHITAN_SMALL_SCRIPT)++pattern SCRIPT_KHMER :: Script+pattern SCRIPT_KHMER = Script (#const KBTS_SCRIPT_KHMER)++pattern SCRIPT_KHOJKI :: Script+pattern SCRIPT_KHOJKI = Script (#const KBTS_SCRIPT_KHOJKI)++pattern SCRIPT_KHUDAWADI :: Script+pattern SCRIPT_KHUDAWADI = Script (#const KBTS_SCRIPT_KHUDAWADI)++pattern SCRIPT_KIRAT_RAI :: Script+pattern SCRIPT_KIRAT_RAI = Script (#const KBTS_SCRIPT_KIRAT_RAI)++pattern SCRIPT_LAO :: Script+pattern SCRIPT_LAO = Script (#const KBTS_SCRIPT_LAO)++pattern SCRIPT_LATIN :: Script+pattern SCRIPT_LATIN = Script (#const KBTS_SCRIPT_LATIN)++pattern SCRIPT_LEPCHA :: Script+pattern SCRIPT_LEPCHA = Script (#const KBTS_SCRIPT_LEPCHA)++pattern SCRIPT_LIMBU :: Script+pattern SCRIPT_LIMBU = Script (#const KBTS_SCRIPT_LIMBU)++pattern SCRIPT_LINEAR_A :: Script+pattern SCRIPT_LINEAR_A = Script (#const KBTS_SCRIPT_LINEAR_A)++pattern SCRIPT_LINEAR_B :: Script+pattern SCRIPT_LINEAR_B = Script (#const KBTS_SCRIPT_LINEAR_B)++pattern SCRIPT_LISU :: Script+pattern SCRIPT_LISU = Script (#const KBTS_SCRIPT_LISU)++pattern SCRIPT_LYCIAN :: Script+pattern SCRIPT_LYCIAN = Script (#const KBTS_SCRIPT_LYCIAN)++pattern SCRIPT_LYDIAN :: Script+pattern SCRIPT_LYDIAN = Script (#const KBTS_SCRIPT_LYDIAN)++pattern SCRIPT_MAHAJANI :: Script+pattern SCRIPT_MAHAJANI = Script (#const KBTS_SCRIPT_MAHAJANI)++pattern SCRIPT_MAKASAR :: Script+pattern SCRIPT_MAKASAR = Script (#const KBTS_SCRIPT_MAKASAR)++pattern SCRIPT_MALAYALAM :: Script+pattern SCRIPT_MALAYALAM = Script (#const KBTS_SCRIPT_MALAYALAM)++pattern SCRIPT_MANDAIC :: Script+pattern SCRIPT_MANDAIC = Script (#const KBTS_SCRIPT_MANDAIC)++pattern SCRIPT_MANICHAEAN :: Script+pattern SCRIPT_MANICHAEAN = Script (#const KBTS_SCRIPT_MANICHAEAN)++pattern SCRIPT_MARCHEN :: Script+pattern SCRIPT_MARCHEN = Script (#const KBTS_SCRIPT_MARCHEN)++pattern SCRIPT_MASARAM_GONDI :: Script+pattern SCRIPT_MASARAM_GONDI = Script (#const KBTS_SCRIPT_MASARAM_GONDI)++pattern SCRIPT_MEDEFAIDRIN :: Script+pattern SCRIPT_MEDEFAIDRIN = Script (#const KBTS_SCRIPT_MEDEFAIDRIN)++pattern SCRIPT_MEETEI_MAYEK :: Script+pattern SCRIPT_MEETEI_MAYEK = Script (#const KBTS_SCRIPT_MEETEI_MAYEK)++pattern SCRIPT_MENDE_KIKAKUI :: Script+pattern SCRIPT_MENDE_KIKAKUI = Script (#const KBTS_SCRIPT_MENDE_KIKAKUI)++pattern SCRIPT_MEROITIC_CURSIVE :: Script+pattern SCRIPT_MEROITIC_CURSIVE = Script (#const KBTS_SCRIPT_MEROITIC_CURSIVE)++pattern SCRIPT_MEROITIC_HIEROGLYPHS :: Script+pattern SCRIPT_MEROITIC_HIEROGLYPHS = Script (#const KBTS_SCRIPT_MEROITIC_HIEROGLYPHS)++pattern SCRIPT_MIAO :: Script+pattern SCRIPT_MIAO = Script (#const KBTS_SCRIPT_MIAO)++pattern SCRIPT_MODI :: Script+pattern SCRIPT_MODI = Script (#const KBTS_SCRIPT_MODI)++pattern SCRIPT_MONGOLIAN :: Script+pattern SCRIPT_MONGOLIAN = Script (#const KBTS_SCRIPT_MONGOLIAN)++pattern SCRIPT_MRO :: Script+pattern SCRIPT_MRO = Script (#const KBTS_SCRIPT_MRO)++pattern SCRIPT_MULTANI :: Script+pattern SCRIPT_MULTANI = Script (#const KBTS_SCRIPT_MULTANI)++pattern SCRIPT_MYANMAR :: Script+pattern SCRIPT_MYANMAR = Script (#const KBTS_SCRIPT_MYANMAR)++pattern SCRIPT_NABATAEAN :: Script+pattern SCRIPT_NABATAEAN = Script (#const KBTS_SCRIPT_NABATAEAN)++pattern SCRIPT_NAG_MUNDARI :: Script+pattern SCRIPT_NAG_MUNDARI = Script (#const KBTS_SCRIPT_NAG_MUNDARI)++pattern SCRIPT_NANDINAGARI :: Script+pattern SCRIPT_NANDINAGARI = Script (#const KBTS_SCRIPT_NANDINAGARI)++pattern SCRIPT_NEWA :: Script+pattern SCRIPT_NEWA = Script (#const KBTS_SCRIPT_NEWA)++pattern SCRIPT_NEW_TAI_LUE :: Script+pattern SCRIPT_NEW_TAI_LUE = Script (#const KBTS_SCRIPT_NEW_TAI_LUE)++pattern SCRIPT_NKO :: Script+pattern SCRIPT_NKO = Script (#const KBTS_SCRIPT_NKO)++pattern SCRIPT_NUSHU :: Script+pattern SCRIPT_NUSHU = Script (#const KBTS_SCRIPT_NUSHU)++pattern SCRIPT_NYIAKENG_PUACHUE_HMONG :: Script+pattern SCRIPT_NYIAKENG_PUACHUE_HMONG = Script (#const KBTS_SCRIPT_NYIAKENG_PUACHUE_HMONG)++pattern SCRIPT_OGHAM :: Script+pattern SCRIPT_OGHAM = Script (#const KBTS_SCRIPT_OGHAM)++pattern SCRIPT_OL_CHIKI :: Script+pattern SCRIPT_OL_CHIKI = Script (#const KBTS_SCRIPT_OL_CHIKI)++pattern SCRIPT_OL_ONAL :: Script+pattern SCRIPT_OL_ONAL = Script (#const KBTS_SCRIPT_OL_ONAL)++pattern SCRIPT_OLD_ITALIC :: Script+pattern SCRIPT_OLD_ITALIC = Script (#const KBTS_SCRIPT_OLD_ITALIC)++pattern SCRIPT_OLD_HUNGARIAN :: Script+pattern SCRIPT_OLD_HUNGARIAN = Script (#const KBTS_SCRIPT_OLD_HUNGARIAN)++pattern SCRIPT_OLD_NORTH_ARABIAN :: Script+pattern SCRIPT_OLD_NORTH_ARABIAN = Script (#const KBTS_SCRIPT_OLD_NORTH_ARABIAN)++pattern SCRIPT_OLD_PERMIC :: Script+pattern SCRIPT_OLD_PERMIC = Script (#const KBTS_SCRIPT_OLD_PERMIC)++pattern SCRIPT_OLD_PERSIAN_CUNEIFORM :: Script+pattern SCRIPT_OLD_PERSIAN_CUNEIFORM = Script (#const KBTS_SCRIPT_OLD_PERSIAN_CUNEIFORM)++pattern SCRIPT_OLD_SOGDIAN :: Script+pattern SCRIPT_OLD_SOGDIAN = Script (#const KBTS_SCRIPT_OLD_SOGDIAN)++pattern SCRIPT_OLD_SOUTH_ARABIAN :: Script+pattern SCRIPT_OLD_SOUTH_ARABIAN = Script (#const KBTS_SCRIPT_OLD_SOUTH_ARABIAN)++pattern SCRIPT_OLD_TURKIC :: Script+pattern SCRIPT_OLD_TURKIC = Script (#const KBTS_SCRIPT_OLD_TURKIC)++pattern SCRIPT_OLD_UYGHUR :: Script+pattern SCRIPT_OLD_UYGHUR = Script (#const KBTS_SCRIPT_OLD_UYGHUR)++pattern SCRIPT_ODIA :: Script+pattern SCRIPT_ODIA = Script (#const KBTS_SCRIPT_ODIA)++pattern SCRIPT_OSAGE :: Script+pattern SCRIPT_OSAGE = Script (#const KBTS_SCRIPT_OSAGE)++pattern SCRIPT_OSMANYA :: Script+pattern SCRIPT_OSMANYA = Script (#const KBTS_SCRIPT_OSMANYA)++pattern SCRIPT_PAHAWH_HMONG :: Script+pattern SCRIPT_PAHAWH_HMONG = Script (#const KBTS_SCRIPT_PAHAWH_HMONG)++pattern SCRIPT_PALMYRENE :: Script+pattern SCRIPT_PALMYRENE = Script (#const KBTS_SCRIPT_PALMYRENE)++pattern SCRIPT_PAU_CIN_HAU :: Script+pattern SCRIPT_PAU_CIN_HAU = Script (#const KBTS_SCRIPT_PAU_CIN_HAU)++pattern SCRIPT_PHAGS_PA :: Script+pattern SCRIPT_PHAGS_PA = Script (#const KBTS_SCRIPT_PHAGS_PA)++pattern SCRIPT_PHOENICIAN :: Script+pattern SCRIPT_PHOENICIAN = Script (#const KBTS_SCRIPT_PHOENICIAN)++pattern SCRIPT_PSALTER_PAHLAVI :: Script+pattern SCRIPT_PSALTER_PAHLAVI = Script (#const KBTS_SCRIPT_PSALTER_PAHLAVI)++pattern SCRIPT_REJANG :: Script+pattern SCRIPT_REJANG = Script (#const KBTS_SCRIPT_REJANG)++pattern SCRIPT_RUNIC :: Script+pattern SCRIPT_RUNIC = Script (#const KBTS_SCRIPT_RUNIC)++pattern SCRIPT_SAMARITAN :: Script+pattern SCRIPT_SAMARITAN = Script (#const KBTS_SCRIPT_SAMARITAN)++pattern SCRIPT_SAURASHTRA :: Script+pattern SCRIPT_SAURASHTRA = Script (#const KBTS_SCRIPT_SAURASHTRA)++pattern SCRIPT_SHARADA :: Script+pattern SCRIPT_SHARADA = Script (#const KBTS_SCRIPT_SHARADA)++pattern SCRIPT_SHAVIAN :: Script+pattern SCRIPT_SHAVIAN = Script (#const KBTS_SCRIPT_SHAVIAN)++pattern SCRIPT_SIDDHAM :: Script+pattern SCRIPT_SIDDHAM = Script (#const KBTS_SCRIPT_SIDDHAM)++pattern SCRIPT_SIGN_WRITING :: Script+pattern SCRIPT_SIGN_WRITING = Script (#const KBTS_SCRIPT_SIGN_WRITING)++pattern SCRIPT_SOGDIAN :: Script+pattern SCRIPT_SOGDIAN = Script (#const KBTS_SCRIPT_SOGDIAN)++pattern SCRIPT_SINHALA :: Script+pattern SCRIPT_SINHALA = Script (#const KBTS_SCRIPT_SINHALA)++pattern SCRIPT_SORA_SOMPENG :: Script+pattern SCRIPT_SORA_SOMPENG = Script (#const KBTS_SCRIPT_SORA_SOMPENG)++pattern SCRIPT_SOYOMBO :: Script+pattern SCRIPT_SOYOMBO = Script (#const KBTS_SCRIPT_SOYOMBO)++pattern SCRIPT_SUMERO_AKKADIAN_CUNEIFORM :: Script+pattern SCRIPT_SUMERO_AKKADIAN_CUNEIFORM = Script (#const KBTS_SCRIPT_SUMERO_AKKADIAN_CUNEIFORM)++pattern SCRIPT_SUNDANESE :: Script+pattern SCRIPT_SUNDANESE = Script (#const KBTS_SCRIPT_SUNDANESE)++pattern SCRIPT_SUNUWAR :: Script+pattern SCRIPT_SUNUWAR = Script (#const KBTS_SCRIPT_SUNUWAR)++pattern SCRIPT_SYLOTI_NAGRI :: Script+pattern SCRIPT_SYLOTI_NAGRI = Script (#const KBTS_SCRIPT_SYLOTI_NAGRI)++pattern SCRIPT_SYRIAC :: Script+pattern SCRIPT_SYRIAC = Script (#const KBTS_SCRIPT_SYRIAC)++pattern SCRIPT_TAGALOG :: Script+pattern SCRIPT_TAGALOG = Script (#const KBTS_SCRIPT_TAGALOG)++pattern SCRIPT_TAGBANWA :: Script+pattern SCRIPT_TAGBANWA = Script (#const KBTS_SCRIPT_TAGBANWA)++pattern SCRIPT_TAI_LE :: Script+pattern SCRIPT_TAI_LE = Script (#const KBTS_SCRIPT_TAI_LE)++pattern SCRIPT_TAI_THAM :: Script+pattern SCRIPT_TAI_THAM = Script (#const KBTS_SCRIPT_TAI_THAM)++pattern SCRIPT_TAI_VIET :: Script+pattern SCRIPT_TAI_VIET = Script (#const KBTS_SCRIPT_TAI_VIET)++pattern SCRIPT_TAKRI :: Script+pattern SCRIPT_TAKRI = Script (#const KBTS_SCRIPT_TAKRI)++pattern SCRIPT_TAMIL :: Script+pattern SCRIPT_TAMIL = Script (#const KBTS_SCRIPT_TAMIL)++pattern SCRIPT_TANGSA :: Script+pattern SCRIPT_TANGSA = Script (#const KBTS_SCRIPT_TANGSA)++pattern SCRIPT_TANGUT :: Script+pattern SCRIPT_TANGUT = Script (#const KBTS_SCRIPT_TANGUT)++pattern SCRIPT_TELUGU :: Script+pattern SCRIPT_TELUGU = Script (#const KBTS_SCRIPT_TELUGU)++pattern SCRIPT_THAANA :: Script+pattern SCRIPT_THAANA = Script (#const KBTS_SCRIPT_THAANA)++pattern SCRIPT_THAI :: Script+pattern SCRIPT_THAI = Script (#const KBTS_SCRIPT_THAI)++pattern SCRIPT_TIBETAN :: Script+pattern SCRIPT_TIBETAN = Script (#const KBTS_SCRIPT_TIBETAN)++pattern SCRIPT_TIFINAGH :: Script+pattern SCRIPT_TIFINAGH = Script (#const KBTS_SCRIPT_TIFINAGH)++pattern SCRIPT_TIRHUTA :: Script+pattern SCRIPT_TIRHUTA = Script (#const KBTS_SCRIPT_TIRHUTA)++pattern SCRIPT_TODHRI :: Script+pattern SCRIPT_TODHRI = Script (#const KBTS_SCRIPT_TODHRI)++pattern SCRIPT_TOTO :: Script+pattern SCRIPT_TOTO = Script (#const KBTS_SCRIPT_TOTO)++pattern SCRIPT_TULU_TIGALARI :: Script+pattern SCRIPT_TULU_TIGALARI = Script (#const KBTS_SCRIPT_TULU_TIGALARI)++pattern SCRIPT_UGARITIC_CUNEIFORM :: Script+pattern SCRIPT_UGARITIC_CUNEIFORM = Script (#const KBTS_SCRIPT_UGARITIC_CUNEIFORM)++pattern SCRIPT_VAI :: Script+pattern SCRIPT_VAI = Script (#const KBTS_SCRIPT_VAI)++pattern SCRIPT_VITHKUQI :: Script+pattern SCRIPT_VITHKUQI = Script (#const KBTS_SCRIPT_VITHKUQI)++pattern SCRIPT_WANCHO :: Script+pattern SCRIPT_WANCHO = Script (#const KBTS_SCRIPT_WANCHO)++pattern SCRIPT_WARANG_CITI :: Script+pattern SCRIPT_WARANG_CITI = Script (#const KBTS_SCRIPT_WARANG_CITI)++pattern SCRIPT_YEZIDI :: Script+pattern SCRIPT_YEZIDI = Script (#const KBTS_SCRIPT_YEZIDI)++pattern SCRIPT_YI :: Script+pattern SCRIPT_YI = Script (#const KBTS_SCRIPT_YI)++pattern SCRIPT_ZANABAZAR_SQUARE :: Script+pattern SCRIPT_ZANABAZAR_SQUARE = Script (#const KBTS_SCRIPT_ZANABAZAR_SQUARE)++scriptNames :: Map Script String+scriptNames = Map.fromList+ [ (SCRIPT_DONT_KNOW, "SCRIPT_DONT_KNOW")+ , (SCRIPT_ADLAM, "SCRIPT_ADLAM")+ , (SCRIPT_AHOM, "SCRIPT_AHOM")+ , (SCRIPT_ANATOLIAN_HIEROGLYPHS, "SCRIPT_ANATOLIAN_HIEROGLYPHS")+ , (SCRIPT_ARABIC, "SCRIPT_ARABIC")+ , (SCRIPT_ARMENIAN, "SCRIPT_ARMENIAN")+ , (SCRIPT_AVESTAN, "SCRIPT_AVESTAN")+ , (SCRIPT_BALINESE, "SCRIPT_BALINESE")+ , (SCRIPT_BAMUM, "SCRIPT_BAMUM")+ , (SCRIPT_BASSA_VAH, "SCRIPT_BASSA_VAH")+ , (SCRIPT_BATAK, "SCRIPT_BATAK")+ , (SCRIPT_BENGALI, "SCRIPT_BENGALI")+ , (SCRIPT_BHAIKSUKI, "SCRIPT_BHAIKSUKI")+ , (SCRIPT_BOPOMOFO, "SCRIPT_BOPOMOFO")+ , (SCRIPT_BRAHMI, "SCRIPT_BRAHMI")+ , (SCRIPT_BUGINESE, "SCRIPT_BUGINESE")+ , (SCRIPT_BUHID, "SCRIPT_BUHID")+ , (SCRIPT_CANADIAN_SYLLABICS, "SCRIPT_CANADIAN_SYLLABICS")+ , (SCRIPT_CARIAN, "SCRIPT_CARIAN")+ , (SCRIPT_CAUCASIAN_ALBANIAN, "SCRIPT_CAUCASIAN_ALBANIAN")+ , (SCRIPT_CHAKMA, "SCRIPT_CHAKMA")+ , (SCRIPT_CHAM, "SCRIPT_CHAM")+ , (SCRIPT_CHEROKEE, "SCRIPT_CHEROKEE")+ , (SCRIPT_CHORASMIAN, "SCRIPT_CHORASMIAN")+ , (SCRIPT_CJK_IDEOGRAPHIC, "SCRIPT_CJK_IDEOGRAPHIC")+ , (SCRIPT_COPTIC, "SCRIPT_COPTIC")+ , (SCRIPT_CYPRIOT_SYLLABARY, "SCRIPT_CYPRIOT_SYLLABARY")+ , (SCRIPT_CYPRO_MINOAN, "SCRIPT_CYPRO_MINOAN")+ , (SCRIPT_CYRILLIC, "SCRIPT_CYRILLIC")+ , (SCRIPT_DEFAULT, "SCRIPT_DEFAULT")+ , (SCRIPT_DEFAULT2, "SCRIPT_DEFAULT2")+ , (SCRIPT_DESERET, "SCRIPT_DESERET")+ , (SCRIPT_DEVANAGARI, "SCRIPT_DEVANAGARI")+ , (SCRIPT_DIVES_AKURU, "SCRIPT_DIVES_AKURU")+ , (SCRIPT_DOGRA, "SCRIPT_DOGRA")+ , (SCRIPT_DUPLOYAN, "SCRIPT_DUPLOYAN")+ , (SCRIPT_EGYPTIAN_HIEROGLYPHS, "SCRIPT_EGYPTIAN_HIEROGLYPHS")+ , (SCRIPT_ELBASAN, "SCRIPT_ELBASAN")+ , (SCRIPT_ELYMAIC, "SCRIPT_ELYMAIC")+ , (SCRIPT_ETHIOPIC, "SCRIPT_ETHIOPIC")+ , (SCRIPT_GARAY, "SCRIPT_GARAY")+ , (SCRIPT_GEORGIAN, "SCRIPT_GEORGIAN")+ , (SCRIPT_GLAGOLITIC, "SCRIPT_GLAGOLITIC")+ , (SCRIPT_GOTHIC, "SCRIPT_GOTHIC")+ , (SCRIPT_GRANTHA, "SCRIPT_GRANTHA")+ , (SCRIPT_GREEK, "SCRIPT_GREEK")+ , (SCRIPT_GUJARATI, "SCRIPT_GUJARATI")+ , (SCRIPT_GUNJALA_GONDI, "SCRIPT_GUNJALA_GONDI")+ , (SCRIPT_GURMUKHI, "SCRIPT_GURMUKHI")+ , (SCRIPT_GURUNG_KHEMA, "SCRIPT_GURUNG_KHEMA")+ , (SCRIPT_HANGUL, "SCRIPT_HANGUL")+ , (SCRIPT_HANIFI_ROHINGYA, "SCRIPT_HANIFI_ROHINGYA")+ , (SCRIPT_HANUNOO, "SCRIPT_HANUNOO")+ , (SCRIPT_HATRAN, "SCRIPT_HATRAN")+ , (SCRIPT_HEBREW, "SCRIPT_HEBREW")+ , (SCRIPT_HIRAGANA, "SCRIPT_HIRAGANA")+ , (SCRIPT_IMPERIAL_ARAMAIC, "SCRIPT_IMPERIAL_ARAMAIC")+ , (SCRIPT_INSCRIPTIONAL_PAHLAVI, "SCRIPT_INSCRIPTIONAL_PAHLAVI")+ , (SCRIPT_INSCRIPTIONAL_PARTHIAN, "SCRIPT_INSCRIPTIONAL_PARTHIAN")+ , (SCRIPT_JAVANESE, "SCRIPT_JAVANESE")+ , (SCRIPT_KAITHI, "SCRIPT_KAITHI")+ , (SCRIPT_KANNADA, "SCRIPT_KANNADA")+ , (SCRIPT_KATAKANA, "SCRIPT_KATAKANA")+ , (SCRIPT_KAWI, "SCRIPT_KAWI")+ , (SCRIPT_KAYAH_LI, "SCRIPT_KAYAH_LI")+ , (SCRIPT_KHAROSHTHI, "SCRIPT_KHAROSHTHI")+ , (SCRIPT_KHITAN_SMALL_SCRIPT, "SCRIPT_KHITAN_SMALL_SCRIPT")+ , (SCRIPT_KHMER, "SCRIPT_KHMER")+ , (SCRIPT_KHOJKI, "SCRIPT_KHOJKI")+ , (SCRIPT_KHUDAWADI, "SCRIPT_KHUDAWADI")+ , (SCRIPT_KIRAT_RAI, "SCRIPT_KIRAT_RAI")+ , (SCRIPT_LAO, "SCRIPT_LAO")+ , (SCRIPT_LATIN, "SCRIPT_LATIN")+ , (SCRIPT_LEPCHA, "SCRIPT_LEPCHA")+ , (SCRIPT_LIMBU, "SCRIPT_LIMBU")+ , (SCRIPT_LINEAR_A, "SCRIPT_LINEAR_A")+ , (SCRIPT_LINEAR_B, "SCRIPT_LINEAR_B")+ , (SCRIPT_LISU, "SCRIPT_LISU")+ , (SCRIPT_LYCIAN, "SCRIPT_LYCIAN")+ , (SCRIPT_LYDIAN, "SCRIPT_LYDIAN")+ , (SCRIPT_MAHAJANI, "SCRIPT_MAHAJANI")+ , (SCRIPT_MAKASAR, "SCRIPT_MAKASAR")+ , (SCRIPT_MALAYALAM, "SCRIPT_MALAYALAM")+ , (SCRIPT_MANDAIC, "SCRIPT_MANDAIC")+ , (SCRIPT_MANICHAEAN, "SCRIPT_MANICHAEAN")+ , (SCRIPT_MARCHEN, "SCRIPT_MARCHEN")+ , (SCRIPT_MASARAM_GONDI, "SCRIPT_MASARAM_GONDI")+ , (SCRIPT_MEDEFAIDRIN, "SCRIPT_MEDEFAIDRIN")+ , (SCRIPT_MEETEI_MAYEK, "SCRIPT_MEETEI_MAYEK")+ , (SCRIPT_MENDE_KIKAKUI, "SCRIPT_MENDE_KIKAKUI")+ , (SCRIPT_MEROITIC_CURSIVE, "SCRIPT_MEROITIC_CURSIVE")+ , (SCRIPT_MEROITIC_HIEROGLYPHS, "SCRIPT_MEROITIC_HIEROGLYPHS")+ , (SCRIPT_MIAO, "SCRIPT_MIAO")+ , (SCRIPT_MODI, "SCRIPT_MODI")+ , (SCRIPT_MONGOLIAN, "SCRIPT_MONGOLIAN")+ , (SCRIPT_MRO, "SCRIPT_MRO")+ , (SCRIPT_MULTANI, "SCRIPT_MULTANI")+ , (SCRIPT_MYANMAR, "SCRIPT_MYANMAR")+ , (SCRIPT_NABATAEAN, "SCRIPT_NABATAEAN")+ , (SCRIPT_NAG_MUNDARI, "SCRIPT_NAG_MUNDARI")+ , (SCRIPT_NANDINAGARI, "SCRIPT_NANDINAGARI")+ , (SCRIPT_NEWA, "SCRIPT_NEWA")+ , (SCRIPT_NEW_TAI_LUE, "SCRIPT_NEW_TAI_LUE")+ , (SCRIPT_NKO, "SCRIPT_NKO")+ , (SCRIPT_NUSHU, "SCRIPT_NUSHU")+ , (SCRIPT_NYIAKENG_PUACHUE_HMONG, "SCRIPT_NYIAKENG_PUACHUE_HMONG")+ , (SCRIPT_OGHAM, "SCRIPT_OGHAM")+ , (SCRIPT_OL_CHIKI, "SCRIPT_OL_CHIKI")+ , (SCRIPT_OL_ONAL, "SCRIPT_OL_ONAL")+ , (SCRIPT_OLD_ITALIC, "SCRIPT_OLD_ITALIC")+ , (SCRIPT_OLD_HUNGARIAN, "SCRIPT_OLD_HUNGARIAN")+ , (SCRIPT_OLD_NORTH_ARABIAN, "SCRIPT_OLD_NORTH_ARABIAN")+ , (SCRIPT_OLD_PERMIC, "SCRIPT_OLD_PERMIC")+ , (SCRIPT_OLD_PERSIAN_CUNEIFORM, "SCRIPT_OLD_PERSIAN_CUNEIFORM")+ , (SCRIPT_OLD_SOGDIAN, "SCRIPT_OLD_SOGDIAN")+ , (SCRIPT_OLD_SOUTH_ARABIAN, "SCRIPT_OLD_SOUTH_ARABIAN")+ , (SCRIPT_OLD_TURKIC, "SCRIPT_OLD_TURKIC")+ , (SCRIPT_OLD_UYGHUR, "SCRIPT_OLD_UYGHUR")+ , (SCRIPT_ODIA, "SCRIPT_ODIA")+ , (SCRIPT_OSAGE, "SCRIPT_OSAGE")+ , (SCRIPT_OSMANYA, "SCRIPT_OSMANYA")+ , (SCRIPT_PAHAWH_HMONG, "SCRIPT_PAHAWH_HMONG")+ , (SCRIPT_PALMYRENE, "SCRIPT_PALMYRENE")+ , (SCRIPT_PAU_CIN_HAU, "SCRIPT_PAU_CIN_HAU")+ , (SCRIPT_PHAGS_PA, "SCRIPT_PHAGS_PA")+ , (SCRIPT_PHOENICIAN, "SCRIPT_PHOENICIAN")+ , (SCRIPT_PSALTER_PAHLAVI, "SCRIPT_PSALTER_PAHLAVI")+ , (SCRIPT_REJANG, "SCRIPT_REJANG")+ , (SCRIPT_RUNIC, "SCRIPT_RUNIC")+ , (SCRIPT_SAMARITAN, "SCRIPT_SAMARITAN")+ , (SCRIPT_SAURASHTRA, "SCRIPT_SAURASHTRA")+ , (SCRIPT_SHARADA, "SCRIPT_SHARADA")+ , (SCRIPT_SHAVIAN, "SCRIPT_SHAVIAN")+ , (SCRIPT_SIDDHAM, "SCRIPT_SIDDHAM")+ , (SCRIPT_SIGN_WRITING, "SCRIPT_SIGN_WRITING")+ , (SCRIPT_SOGDIAN, "SCRIPT_SOGDIAN")+ , (SCRIPT_SINHALA, "SCRIPT_SINHALA")+ , (SCRIPT_SORA_SOMPENG, "SCRIPT_SORA_SOMPENG")+ , (SCRIPT_SOYOMBO, "SCRIPT_SOYOMBO")+ , (SCRIPT_SUMERO_AKKADIAN_CUNEIFORM, "SCRIPT_SUMERO_AKKADIAN_CUNEIFORM")+ , (SCRIPT_SUNDANESE, "SCRIPT_SUNDANESE")+ , (SCRIPT_SUNUWAR, "SCRIPT_SUNUWAR")+ , (SCRIPT_SYLOTI_NAGRI, "SCRIPT_SYLOTI_NAGRI")+ , (SCRIPT_SYRIAC, "SCRIPT_SYRIAC")+ , (SCRIPT_TAGALOG, "SCRIPT_TAGALOG")+ , (SCRIPT_TAGBANWA, "SCRIPT_TAGBANWA")+ , (SCRIPT_TAI_LE, "SCRIPT_TAI_LE")+ , (SCRIPT_TAI_THAM, "SCRIPT_TAI_THAM")+ , (SCRIPT_TAI_VIET, "SCRIPT_TAI_VIET")+ , (SCRIPT_TAKRI, "SCRIPT_TAKRI")+ , (SCRIPT_TAMIL, "SCRIPT_TAMIL")+ , (SCRIPT_TANGSA, "SCRIPT_TANGSA")+ , (SCRIPT_TANGUT, "SCRIPT_TANGUT")+ , (SCRIPT_TELUGU, "SCRIPT_TELUGU")+ , (SCRIPT_THAANA, "SCRIPT_THAANA")+ , (SCRIPT_THAI, "SCRIPT_THAI")+ , (SCRIPT_TIBETAN, "SCRIPT_TIBETAN")+ , (SCRIPT_TIFINAGH, "SCRIPT_TIFINAGH")+ , (SCRIPT_TIRHUTA, "SCRIPT_TIRHUTA")+ , (SCRIPT_TODHRI, "SCRIPT_TODHRI")+ , (SCRIPT_TOTO, "SCRIPT_TOTO")+ , (SCRIPT_TULU_TIGALARI, "SCRIPT_TULU_TIGALARI")+ , (SCRIPT_UGARITIC_CUNEIFORM, "SCRIPT_UGARITIC_CUNEIFORM")+ , (SCRIPT_VAI, "SCRIPT_VAI")+ , (SCRIPT_VITHKUQI, "SCRIPT_VITHKUQI")+ , (SCRIPT_WANCHO, "SCRIPT_WANCHO")+ , (SCRIPT_WARANG_CITI, "SCRIPT_WARANG_CITI")+ , (SCRIPT_YEZIDI, "SCRIPT_YEZIDI")+ , (SCRIPT_YI, "SCRIPT_YI")+ , (SCRIPT_ZANABAZAR_SQUARE, "SCRIPT_ZANABAZAR_SQUARE")+ ]
+ src/KB/Text/Shape/FFI/Flags.hsc view
@@ -0,0 +1,340 @@+module KB.Text.Shape.FFI.Flags+ ( module KB.Text.Shape.FFI.Flags+ -- , module RE+ ) where++import Foreign++-- import KB.Text.Shape.FFI.Flags.Foo as RE++#include "kb_text_shape.h"++-- * Flags++-- ** BreakFlags++newtype BreakFlags = BreakFlags Word32+ deriving (Eq, Ord)+ deriving newtype (Storable, Bits)++instance Semigroup BreakFlags where+ {-# INLINE (<>) #-}+ (<>) = (.|.)++instance Monoid BreakFlags where+ {-# INLINE mempty #-}+ mempty = BreakFlags 0++instance Show BreakFlags where+ showsPrec = showsFlags breakBits "BreakFlags" \(BreakFlags i) -> i++breakBits :: [(BreakFlags, String)]+breakBits =+ [ (BREAK_FLAG_DIRECTION, "BREAK_FLAG_DIRECTION")+ , (BREAK_FLAG_SCRIPT, "BREAK_FLAG_SCRIPT")+ , (BREAK_FLAG_GRAPHEME, "BREAK_FLAG_GRAPHEME")+ , (BREAK_FLAG_WORD, "BREAK_FLAG_WORD")+ , (BREAK_FLAG_LINE_SOFT, "BREAK_FLAG_LINE_SOFT")+ , (BREAK_FLAG_LINE_HARD, "BREAK_FLAG_LINE_HARD")+ , (BREAK_FLAG_MANUAL, "BREAK_FLAG_MANUAL")+ , (BREAK_FLAG_PARAGRAPH_DIRECTION, "BREAK_FLAG_PARAGRAPH_DIRECTION")+ ]++pattern BREAK_FLAG_DIRECTION :: BreakFlags+pattern BREAK_FLAG_DIRECTION = BreakFlags (#const KBTS_BREAK_FLAG_DIRECTION)++pattern BREAK_FLAG_SCRIPT :: BreakFlags+pattern BREAK_FLAG_SCRIPT = BreakFlags (#const KBTS_BREAK_FLAG_SCRIPT)++pattern BREAK_FLAG_GRAPHEME :: BreakFlags+pattern BREAK_FLAG_GRAPHEME = BreakFlags (#const KBTS_BREAK_FLAG_GRAPHEME)++pattern BREAK_FLAG_WORD :: BreakFlags+pattern BREAK_FLAG_WORD = BreakFlags (#const KBTS_BREAK_FLAG_WORD)++pattern BREAK_FLAG_LINE_SOFT :: BreakFlags+pattern BREAK_FLAG_LINE_SOFT = BreakFlags (#const KBTS_BREAK_FLAG_LINE_SOFT)++pattern BREAK_FLAG_LINE_HARD :: BreakFlags+pattern BREAK_FLAG_LINE_HARD = BreakFlags (#const KBTS_BREAK_FLAG_LINE_HARD)++pattern BREAK_FLAG_MANUAL :: BreakFlags+pattern BREAK_FLAG_MANUAL = BreakFlags (#const KBTS_BREAK_FLAG_MANUAL)++pattern BREAK_FLAG_PARAGRAPH_DIRECTION :: BreakFlags+pattern BREAK_FLAG_PARAGRAPH_DIRECTION = BreakFlags (#const KBTS_BREAK_FLAG_PARAGRAPH_DIRECTION)++-- | `BREAK_FLAG_LINE_SOFT` | `BREAK_FLAG_LINE_HARD`+pattern BREAK_FLAG_LINE :: BreakFlags+pattern BREAK_FLAG_LINE = BreakFlags (#const KBTS_BREAK_FLAG_LINE)++-- | `BREAK_FLAG_DIRECTION` | `BREAK_FLAG_SCRIPT` | `BREAK_FLAG_GRAPHEME` | `BREAK_FLAG_WORD` | `BREAK_FLAG_LINE_SOFT` | `BREAK_FLAG_LINE_HARD`.+pattern BREAK_FLAG_ANY :: BreakFlags+pattern BREAK_FLAG_ANY = BreakFlags (#const KBTS_BREAK_FLAG_ANY)++-- ** BreakStateFlags++newtype BreakStateFlags = BreakStateFlags Word32+ deriving (Eq, Ord)+ deriving newtype (Storable, Bits)++instance Semigroup BreakStateFlags where+ {-# INLINE (<>) #-}+ (<>) = (.|.)++instance Monoid BreakStateFlags where+ {-# INLINE mempty #-}+ mempty = BreakStateFlags 0++instance Show BreakStateFlags where+ showsPrec = showsFlags breakStateBits "BreakStateFlags" \(BreakStateFlags i) -> i++breakStateBits :: [(BreakStateFlags, String)]+breakStateBits =+ [ (BREAK_STATE_FLAG_STARTED, "BREAK_STATE_FLAG_STARTED")+ , (BREAK_STATE_FLAG_END, "BREAK_STATE_FLAG_END")+ , (BREAK_STATE_FLAG_SAW_R_AFTER_L, "BREAK_STATE_FLAG_SAW_R_AFTER_L")+ , (BREAK_STATE_FLAG_SAW_AL_AFTER_LR, "BREAK_STATE_FLAG_SAW_AL_AFTER_LR")+ , (BREAK_STATE_FLAG_LAST_WAS_BRACKET, "BREAK_STATE_FLAG_LAST_WAS_BRACKET")+ ]++pattern BREAK_STATE_FLAG_STARTED :: BreakStateFlags+pattern BREAK_STATE_FLAG_STARTED = BreakStateFlags (#const KBTS_BREAK_STATE_FLAG_STARTED)++pattern BREAK_STATE_FLAG_END :: BreakStateFlags+pattern BREAK_STATE_FLAG_END = BreakStateFlags (#const KBTS_BREAK_STATE_FLAG_END)++-- Bidirectional flags++pattern BREAK_STATE_FLAG_SAW_R_AFTER_L :: BreakStateFlags+pattern BREAK_STATE_FLAG_SAW_R_AFTER_L = BreakStateFlags (#const KBTS_BREAK_STATE_FLAG_SAW_R_AFTER_L)++pattern BREAK_STATE_FLAG_SAW_AL_AFTER_LR :: BreakStateFlags+pattern BREAK_STATE_FLAG_SAW_AL_AFTER_LR = BreakStateFlags (#const KBTS_BREAK_STATE_FLAG_SAW_AL_AFTER_LR)++pattern BREAK_STATE_FLAG_LAST_WAS_BRACKET :: BreakStateFlags+pattern BREAK_STATE_FLAG_LAST_WAS_BRACKET = BreakStateFlags (#const KBTS_BREAK_STATE_FLAG_LAST_WAS_BRACKET)++-- ** BreakConfigFlags++newtype BreakConfigFlags = BreakConfigFlags Word32+ deriving (Eq, Ord)+ deriving newtype (Storable, Bits)++instance Semigroup BreakConfigFlags where+ {-# INLINE (<>) #-}+ (<>) = (.|.)++instance Monoid BreakConfigFlags where+ {-# INLINE mempty #-}+ mempty = BreakConfigFlags 0++instance Show BreakConfigFlags where+ showsPrec = showsFlags breakConfigBits "BreakConfigFlags" \(BreakConfigFlags i) -> i++breakConfigBits :: [(BreakConfigFlags, String)]+breakConfigBits =+ [ (BREAK_CONFIG_FLAG_END_OF_TEXT_GENERATES_HARD_LINE_BREAK, "BREAK_CONFIG_FLAG_END_OF_TEXT_GENERATES_HARD_LINE_BREAK")+ ]++pattern BREAK_CONFIG_FLAG_END_OF_TEXT_GENERATES_HARD_LINE_BREAK :: BreakConfigFlags+pattern BREAK_CONFIG_FLAG_END_OF_TEXT_GENERATES_HARD_LINE_BREAK = BreakConfigFlags (#const KBTS_BREAK_CONFIG_FLAG_END_OF_TEXT_GENERATES_HARD_LINE_BREAK)++-- ** FontStyleFlags++newtype FontStyleFlags = FontStyleFlags Word32+ deriving (Eq)+ deriving newtype (Storable, Bits)++instance Semigroup FontStyleFlags where+ {-# INLINE (<>) #-}+ (<>) = (.|.)++instance Monoid FontStyleFlags where+ {-# INLINE mempty #-}+ mempty = FontStyleFlags 0++instance Show FontStyleFlags where+ showsPrec = showsFlags fontStyleBits "FontStyleFlags" \(FontStyleFlags i) -> i++fontStyleBits :: [(FontStyleFlags, String)]+fontStyleBits =+ [ (FONT_STYLE_FLAG_REGULAR, "FONT_STYLE_FLAG_REGULAR")+ , (FONT_STYLE_FLAG_ITALIC, "FONT_STYLE_FLAG_ITALIC")+ , (FONT_STYLE_FLAG_BOLD, "FONT_STYLE_FLAG_BOLD")+ ]++pattern FONT_STYLE_FLAG_REGULAR :: FontStyleFlags+pattern FONT_STYLE_FLAG_REGULAR = FontStyleFlags (#const KBTS_FONT_STYLE_FLAG_REGULAR)++pattern FONT_STYLE_FLAG_ITALIC :: FontStyleFlags+pattern FONT_STYLE_FLAG_ITALIC = FontStyleFlags (#const KBTS_FONT_STYLE_FLAG_ITALIC)++pattern FONT_STYLE_FLAG_BOLD :: FontStyleFlags+pattern FONT_STYLE_FLAG_BOLD = FontStyleFlags (#const KBTS_FONT_STYLE_FLAG_BOLD)++-- ** GlyphFlags++newtype GlyphFlags = GlyphFlags Word32+ deriving (Eq)+ deriving newtype (Storable, Bits)++instance Semigroup GlyphFlags where+ {-# INLINE (<>) #-}+ (<>) = (.|.)++instance Monoid GlyphFlags where+ {-# INLINE mempty #-}+ mempty = GlyphFlags 0++instance Show GlyphFlags where+ showsPrec = showsFlags glyphBits "GlyphFlags" \(GlyphFlags i) -> i++glyphBits :: [(GlyphFlags, String)]+glyphBits =+ [ (GLYPH_FLAG_ISOL, "GLYPH_FLAG_ISOL")+ , (GLYPH_FLAG_FINA, "GLYPH_FLAG_FINA")+ , (GLYPH_FLAG_FIN2, "GLYPH_FLAG_FIN2")+ , (GLYPH_FLAG_FIN3, "GLYPH_FLAG_FIN3")+ , (GLYPH_FLAG_MEDI, "GLYPH_FLAG_MEDI")+ , (GLYPH_FLAG_MED2, "GLYPH_FLAG_MED2")+ , (GLYPH_FLAG_INIT, "GLYPH_FLAG_INIT")+ , (GLYPH_FLAG_LJMO, "GLYPH_FLAG_LJMO")+ , (GLYPH_FLAG_VJMO, "GLYPH_FLAG_VJMO")+ , (GLYPH_FLAG_TJMO, "GLYPH_FLAG_TJMO")+ , (GLYPH_FLAG_RPHF, "GLYPH_FLAG_RPHF")+ , (GLYPH_FLAG_BLWF, "GLYPH_FLAG_BLWF")+ , (GLYPH_FLAG_HALF, "GLYPH_FLAG_HALF")+ , (GLYPH_FLAG_PSTF, "GLYPH_FLAG_PSTF")+ , (GLYPH_FLAG_ABVF, "GLYPH_FLAG_ABVF")+ , (GLYPH_FLAG_PREF, "GLYPH_FLAG_PREF")+ , (GLYPH_FLAG_NUMR, "GLYPH_FLAG_NUMR")+ , (GLYPH_FLAG_FRAC, "GLYPH_FLAG_FRAC")+ , (GLYPH_FLAG_DNOM, "GLYPH_FLAG_DNOM")+ , (GLYPH_FLAG_CFAR, "GLYPH_FLAG_CFAR")+ , (GLYPH_FLAG_DO_NOT_DECOMPOSE, "GLYPH_FLAG_DO_NOT_DECOMPOSE")+ , (GLYPH_FLAG_FIRST_IN_MULTIPLE_SUBSTITUTION, "GLYPH_FLAG_FIRST_IN_MULTIPLE_SUBSTITUTION")+ , (GLYPH_FLAG_NO_BREAK, "GLYPH_FLAG_NO_BREAK")+ , (GLYPH_FLAG_CURSIVE, "GLYPH_FLAG_CURSIVE")+ , (GLYPH_FLAG_GENERATED_BY_GSUB, "GLYPH_FLAG_GENERATED_BY_GSUB")+ , (GLYPH_FLAG_USED_IN_GPOS, "GLYPH_FLAG_USED_IN_GPOS")+ , (GLYPH_FLAG_STCH_ENDPOINT, "GLYPH_FLAG_STCH_ENDPOINT")+ , (GLYPH_FLAG_STCH_EXTENSION, "GLYPH_FLAG_STCH_EXTENSION")+ , (GLYPH_FLAG_LIGATURE, "GLYPH_FLAG_LIGATURE")+ , (GLYPH_FLAG_MULTIPLE_SUBSTITUTION, "GLYPH_FLAG_MULTIPLE_SUBSTITUTION")+ ]++pattern GLYPH_FLAG_ISOL :: GlyphFlags+pattern GLYPH_FLAG_ISOL = GlyphFlags (#const KBTS_GLYPH_FLAG_ISOL)++pattern GLYPH_FLAG_FINA :: GlyphFlags+pattern GLYPH_FLAG_FINA = GlyphFlags (#const KBTS_GLYPH_FLAG_FINA)++pattern GLYPH_FLAG_FIN2 :: GlyphFlags+pattern GLYPH_FLAG_FIN2 = GlyphFlags (#const KBTS_GLYPH_FLAG_FIN2)++pattern GLYPH_FLAG_FIN3 :: GlyphFlags+pattern GLYPH_FLAG_FIN3 = GlyphFlags (#const KBTS_GLYPH_FLAG_FIN3)++pattern GLYPH_FLAG_MEDI :: GlyphFlags+pattern GLYPH_FLAG_MEDI = GlyphFlags (#const KBTS_GLYPH_FLAG_MEDI)++pattern GLYPH_FLAG_MED2 :: GlyphFlags+pattern GLYPH_FLAG_MED2 = GlyphFlags (#const KBTS_GLYPH_FLAG_MED2)++pattern GLYPH_FLAG_INIT :: GlyphFlags+pattern GLYPH_FLAG_INIT = GlyphFlags (#const KBTS_GLYPH_FLAG_INIT)++pattern GLYPH_FLAG_LJMO :: GlyphFlags+pattern GLYPH_FLAG_LJMO = GlyphFlags (#const KBTS_GLYPH_FLAG_LJMO)++pattern GLYPH_FLAG_VJMO :: GlyphFlags+pattern GLYPH_FLAG_VJMO = GlyphFlags (#const KBTS_GLYPH_FLAG_VJMO)++pattern GLYPH_FLAG_TJMO :: GlyphFlags+pattern GLYPH_FLAG_TJMO = GlyphFlags (#const KBTS_GLYPH_FLAG_TJMO)++pattern GLYPH_FLAG_RPHF :: GlyphFlags+pattern GLYPH_FLAG_RPHF = GlyphFlags (#const KBTS_GLYPH_FLAG_RPHF)++pattern GLYPH_FLAG_BLWF :: GlyphFlags+pattern GLYPH_FLAG_BLWF = GlyphFlags (#const KBTS_GLYPH_FLAG_BLWF)++pattern GLYPH_FLAG_HALF :: GlyphFlags+pattern GLYPH_FLAG_HALF = GlyphFlags (#const KBTS_GLYPH_FLAG_HALF)++pattern GLYPH_FLAG_PSTF :: GlyphFlags+pattern GLYPH_FLAG_PSTF = GlyphFlags (#const KBTS_GLYPH_FLAG_PSTF)++pattern GLYPH_FLAG_ABVF :: GlyphFlags+pattern GLYPH_FLAG_ABVF = GlyphFlags (#const KBTS_GLYPH_FLAG_ABVF)++pattern GLYPH_FLAG_PREF :: GlyphFlags+pattern GLYPH_FLAG_PREF = GlyphFlags (#const KBTS_GLYPH_FLAG_PREF)++pattern GLYPH_FLAG_NUMR :: GlyphFlags+pattern GLYPH_FLAG_NUMR = GlyphFlags (#const KBTS_GLYPH_FLAG_NUMR)++pattern GLYPH_FLAG_FRAC :: GlyphFlags+pattern GLYPH_FLAG_FRAC = GlyphFlags (#const KBTS_GLYPH_FLAG_FRAC)++pattern GLYPH_FLAG_DNOM :: GlyphFlags+pattern GLYPH_FLAG_DNOM = GlyphFlags (#const KBTS_GLYPH_FLAG_DNOM)++pattern GLYPH_FLAG_CFAR :: GlyphFlags+pattern GLYPH_FLAG_CFAR = GlyphFlags (#const KBTS_GLYPH_FLAG_CFAR)++pattern GLYPH_FLAG_DO_NOT_DECOMPOSE :: GlyphFlags+pattern GLYPH_FLAG_DO_NOT_DECOMPOSE = GlyphFlags (#const KBTS_GLYPH_FLAG_DO_NOT_DECOMPOSE)++pattern GLYPH_FLAG_FIRST_IN_MULTIPLE_SUBSTITUTION :: GlyphFlags+pattern GLYPH_FLAG_FIRST_IN_MULTIPLE_SUBSTITUTION = GlyphFlags (#const KBTS_GLYPH_FLAG_FIRST_IN_MULTIPLE_SUBSTITUTION)++pattern GLYPH_FLAG_NO_BREAK :: GlyphFlags+pattern GLYPH_FLAG_NO_BREAK = GlyphFlags (#const KBTS_GLYPH_FLAG_NO_BREAK)++pattern GLYPH_FLAG_CURSIVE :: GlyphFlags+pattern GLYPH_FLAG_CURSIVE = GlyphFlags (#const KBTS_GLYPH_FLAG_CURSIVE)++pattern GLYPH_FLAG_GENERATED_BY_GSUB :: GlyphFlags+pattern GLYPH_FLAG_GENERATED_BY_GSUB = GlyphFlags (#const KBTS_GLYPH_FLAG_GENERATED_BY_GSUB)++pattern GLYPH_FLAG_USED_IN_GPOS :: GlyphFlags+pattern GLYPH_FLAG_USED_IN_GPOS = GlyphFlags (#const KBTS_GLYPH_FLAG_USED_IN_GPOS)++pattern GLYPH_FLAG_STCH_ENDPOINT :: GlyphFlags+pattern GLYPH_FLAG_STCH_ENDPOINT = GlyphFlags (#const KBTS_GLYPH_FLAG_STCH_ENDPOINT)++pattern GLYPH_FLAG_STCH_EXTENSION :: GlyphFlags+pattern GLYPH_FLAG_STCH_EXTENSION = GlyphFlags (#const KBTS_GLYPH_FLAG_STCH_EXTENSION)++pattern GLYPH_FLAG_LIGATURE :: GlyphFlags+pattern GLYPH_FLAG_LIGATURE = GlyphFlags (#const KBTS_GLYPH_FLAG_LIGATURE)++pattern GLYPH_FLAG_MULTIPLE_SUBSTITUTION :: GlyphFlags+pattern GLYPH_FLAG_MULTIPLE_SUBSTITUTION = GlyphFlags (#const KBTS_GLYPH_FLAG_MULTIPLE_SUBSTITUTION)++-- * Flag utils++{-# INLINE showsFlags #-}+showsFlags :: (Bits a, Num x, Eq x, Show x) => [(a, String)] -> String -> (a -> x) -> Int -> a -> ShowS+showsFlags knownBits typeName unwrap d combined =+ case (remains, found) of+ (_, []) -> showParen (d > 10) showsRemains+ (0, [(_single, name)]) -> showString name+ (0, (_, initial) : rest) -> showParen (d > 10) $ showString initial . foldr (\(_flag, name) next -> showString " <> " . showString name . next) id rest+ (_, some) -> showParen (d > 10) $ foldr (\(_flag, name) next -> showString name . showString " <> " . next) showsRemains some+ where+ remains = unwrap remains'+ (remains', found) = splitFlags knownBits combined+ showsRemains = showString typeName . showString (' ' : show remains)++splitFlags+ :: Bits a+ => [(a, b)] -- static part+ -> a -> (a, [(a, b)]) -- unpacker function+splitFlags flagBits combined = foldr testFst (combined, []) flagBits+ where+ testFst pair@(flagBit, _) acc@(remaining, found)+ | remaining .&. flagBit == flagBit = (remaining .^. flagBit, pair : found)+ | otherwise = acc
+ src/KB/Text/Shape/FFI/Handles.hsc view
@@ -0,0 +1,41 @@+module KB.Text.Shape.FFI.Handles where++import Foreign+import Data.Coerce (Coercible, coerce)++#include "kb_text_shape.h"++{-# INLINE intHandle #-}+intHandle :: Coercible h (Ptr a) => h -> Int+intHandle ptrLike = i+ where+ IntPtr i = ptrToIntPtr (coerce ptrLike)++-- | An opaque handle to the shaping context..+newtype ShapeContext = ShapeContext (Ptr ShapeContext)+ deriving (Eq, Ord, Show)+ deriving newtype (Storable)++-- | An opaque handle to the font data.+newtype Font = Font (Ptr Font)+ deriving (Eq, Ord, Show)+ deriving newtype (Storable)++{- | Amount of bytes needed to hold the font data structure++Usually you don't have to look inside, but may have to allocate one to get the 'Font' handle.+-}+sizeOfFontData :: Int+sizeOfFontData = #size kbts_font++newtype ShapeConfig = ShapeConfig (Ptr ShapeConfig)+ deriving (Eq, Ord, Show)+ deriving newtype (Storable)++newtype GlyphConfig = GlyphConfig (Ptr GlyphConfig)+ deriving (Eq, Ord, Show)+ deriving newtype (Storable)++newtype BreakState = BreakState (Ptr BreakState)+ deriving (Eq, Ord, Show)+ deriving newtype (Storable)
+ src/KB/Text/Shape/FFI/Iterators.hsc view
@@ -0,0 +1,21 @@+module KB.Text.Shape.FFI.Iterators where++import Prelude hiding (id, error)++import Foreign+import Foreign.C++import KB.Text.Shape.FFI.Structs++#include "kb_text_shape.h"++-- | @int kbts_GlyphIteratorNext(kbts_glyph_iterator *It, kbts_glyph **Glyph);@+foreign import ccall "kbts_GlyphIteratorNext" kbts_GlyphIteratorNext+ :: Ptr GlyphIterator+ -> Ptr (Ptr Glyph)+ -> IO Int++-- | @int kbts_GlyphIteratorIsValid(kbts_glyph_iterator *It);@+foreign import ccall "kbts_GlyphIteratorIsValid" kbts_GlyphIteratorIsValid+ :: Ptr GlyphIterator+ -> CInt
+ src/KB/Text/Shape/FFI/Structs.hsc view
@@ -0,0 +1,484 @@+module KB.Text.Shape.FFI.Structs where++import Prelude hiding (id, error)++import Foreign+import Foreign.C++import KB.Text.Shape.FFI.Allocator (Allocator)+import KB.Text.Shape.FFI.Enums+import KB.Text.Shape.FFI.Flags+import KB.Text.Shape.FFI.Handles++#include "kb_text_shape.h"++data FontInfo = FontInfo+ { strings :: [Ptr CChar] -- ^ @char *Strings[KBTS_FONT_INFO_STRING_ID_COUNT]@+ , stringLengths :: [Word16] -- ^ @kbts_u16 StringLengths[KBTS_FONT_INFO_STRING_ID_COUNT]@++ , styleFlags :: FontStyleFlags+ , weight :: FontWeight+ , width :: FontWidth+ } deriving (Eq, Show)++instance Storable FontInfo where+ alignment ~_ = #alignment kbts_font_info+ sizeOf ~_ = #size kbts_font_info++ peek ptr = do+ strings <- peekArray FONT_INFO_STRING_ID_COUNT $ ptr `plusPtr` (#offset kbts_font_info, Strings)+ stringLengths <- peekArray FONT_INFO_STRING_ID_COUNT $ ptr `plusPtr` (#offset kbts_font_info, StringLengths)+ styleFlags <- (#peek kbts_font_info, StyleFlags) ptr+ weight <- (#peek kbts_font_info, Weight) ptr+ width <- (#peek kbts_font_info, Width) ptr+ pure FontInfo{..}++ poke ptr FontInfo{..} = do+ pokeArray (ptr `plusPtr` (#offset kbts_font_info, Strings)) strings+ pokeArray (ptr `plusPtr` (#offset kbts_font_info, StringLengths)) stringLengths+ (#poke kbts_font_info, StyleFlags) ptr styleFlags+ (#poke kbts_font_info, Weight) ptr weight+ (#poke kbts_font_info, Width) ptr width++data GlyphIterator = GlyphIterator+ { glyphStorage :: Ptr GlyphStorage+ , currentGlyph :: Ptr Glyph++ , lastAdvanceX :: Int+ , x :: Int+ , y :: Int+ }+ deriving (Show)++instance Storable GlyphIterator where+ alignment ~_ = #alignment kbts_glyph_iterator+ sizeOf ~_ = #size kbts_glyph_iterator++ peek ptr = do+ glyphStorage <- (#peek kbts_glyph_iterator, GlyphStorage) ptr+ currentGlyph <- (#peek kbts_glyph_iterator, CurrentGlyph) ptr+ lastAdvanceX <- fromIntegral @CInt <$> (#peek kbts_glyph_iterator, LastAdvanceX) ptr+ x <- fromIntegral @CInt <$> (#peek kbts_glyph_iterator, X) ptr+ y <- fromIntegral @CInt <$> (#peek kbts_glyph_iterator, Y) ptr+ pure GlyphIterator{..}++ poke ptr GlyphIterator{..} = do+ (#poke kbts_glyph_iterator, GlyphStorage) ptr glyphStorage+ (#poke kbts_glyph_iterator, CurrentGlyph) ptr currentGlyph+ (#poke kbts_glyph_iterator, LastAdvanceX) ptr $ fromIntegral @_ @CInt lastAdvanceX+ (#poke kbts_glyph_iterator, X) ptr $ fromIntegral @_ @CInt x+ (#poke kbts_glyph_iterator, Y) ptr $ fromIntegral @_ @CInt y++data CodepointIterator = CodepointIterator+ { codepoint :: Ptr Codepoint+ , context :: ShapeContext++ , endBlockIndex :: Word32+ , onePastLastCodepointIndex :: Word32+ , blockIndex :: Word32+ , codepointIndex :: Word32+ , currentBlockCodepointCount :: Word32+ , flatCodepointIndex :: Word32+ }+ deriving (Show)++instance Storable CodepointIterator where+ alignment ~_ = #alignment kbts_shape_codepoint_iterator+ sizeOf ~_ = #size kbts_shape_codepoint_iterator++ peek ptr = do+ codepoint <- (#peek kbts_shape_codepoint_iterator, Codepoint) ptr+ context <- (#peek kbts_shape_codepoint_iterator, Context) ptr+ endBlockIndex <- (#peek kbts_shape_codepoint_iterator, EndBlockIndex) ptr+ onePastLastCodepointIndex <- (#peek kbts_shape_codepoint_iterator, OnePastLastCodepointIndex) ptr+ blockIndex <- (#peek kbts_shape_codepoint_iterator, BlockIndex) ptr+ codepointIndex <- (#peek kbts_shape_codepoint_iterator, CodepointIndex) ptr+ currentBlockCodepointCount <- (#peek kbts_shape_codepoint_iterator, CurrentBlockCodepointCount) ptr+ flatCodepointIndex <- (#peek kbts_shape_codepoint_iterator, FlatCodepointIndex) ptr+ pure CodepointIterator{..}++ poke ptr CodepointIterator{..} = do+ (#poke kbts_shape_codepoint_iterator, Codepoint) ptr codepoint+ (#poke kbts_shape_codepoint_iterator, Context) ptr context+ (#poke kbts_shape_codepoint_iterator, EndBlockIndex) ptr endBlockIndex+ (#poke kbts_shape_codepoint_iterator, OnePastLastCodepointIndex) ptr onePastLastCodepointIndex+ (#poke kbts_shape_codepoint_iterator, BlockIndex) ptr blockIndex+ (#poke kbts_shape_codepoint_iterator, CodepointIndex) ptr codepointIndex+ (#poke kbts_shape_codepoint_iterator, CurrentBlockCodepointCount) ptr currentBlockCodepointCount+ (#poke kbts_shape_codepoint_iterator, FlatCodepointIndex) ptr flatCodepointIndex++data Run = Run+ { font :: Font+ , script :: Script+ , paragraphDirection :: Direction+ , direction :: Direction+ , flags :: BreakFlags++ , glyphs :: GlyphIterator+ }+ deriving (Show)++runGlyphIterator :: Ptr Run -> Ptr GlyphIterator+runGlyphIterator runPtr = runPtr `plusPtr` (#offset kbts_run, Glyphs)++instance Storable Run where+ alignment ~_ = #alignment kbts_run+ sizeOf ~_ = #size kbts_run++ peek ptr = do+ font <- (#peek kbts_run, Font) ptr+ script <- (#peek kbts_run, Script) ptr+ paragraphDirection <- (#peek kbts_run, ParagraphDirection) ptr+ direction <- (#peek kbts_run, Direction) ptr+ flags <- (#peek kbts_run, Flags) ptr++ glyphs <- (#peek kbts_run, Glyphs) ptr+ pure Run{..}++ poke ptr Run{..} = do+ (#poke kbts_run, Font) ptr font+ (#poke kbts_run, Script) ptr script+ (#poke kbts_run, ParagraphDirection) ptr paragraphDirection+ (#poke kbts_run, Direction) ptr direction+ (#poke kbts_run, Flags) ptr flags+ (#poke kbts_run, Glyphs) ptr glyphs++data Arena = Arena+ { allocator :: FunPtr Allocator+ , allocatorData :: Ptr ()++ , blockSentinel :: ArenaBlockHeader+ , freeBlockSentinel :: ArenaBlockHeader+ , error :: Int+ }+ deriving (Show)++instance Storable Arena where+ alignment ~_ = #alignment kbts_arena+ sizeOf ~_ = #size kbts_arena+ peek ptr = do+ allocator <- (#peek kbts_arena, Allocator) ptr+ allocatorData <- (#peek kbts_arena, AllocatorData) ptr+ blockSentinel <- (#peek kbts_arena, BlockSentinel) ptr+ freeBlockSentinel <- (#peek kbts_arena, FreeBlockSentinel) ptr+ error <- (#peek kbts_arena, Error) ptr+ pure Arena{..}+ poke ptr Arena{..} = do+ (#poke kbts_arena, Allocator) ptr allocator+ (#poke kbts_arena, AllocatorData) ptr allocatorData+ (#poke kbts_arena, BlockSentinel) ptr blockSentinel+ (#poke kbts_arena, FreeBlockSentinel) ptr freeBlockSentinel+ (#poke kbts_arena, Error) ptr error++data ArenaBlockHeader = ArenaBlockHeader+ { prev :: Ptr ArenaBlockHeader+ , next :: Ptr ArenaBlockHeader+ }+ deriving (Show)++instance Storable ArenaBlockHeader where+ alignment ~_ = #alignment kbts_arena_block_header+ sizeOf ~_ = #size kbts_arena_block_header+ peek ptr = do+ prev <- (#peek kbts_arena_block_header, Prev) ptr+ next <- (#peek kbts_arena_block_header, Next) ptr+ pure ArenaBlockHeader{..}+ poke ptr ArenaBlockHeader{..} = do+ (#poke kbts_arena_block_header, Prev) ptr prev+ (#poke kbts_arena_block_header, Next) ptr next++data GlyphStorage = GlyphStorage+ { arena :: Arena++ , glyphSentinel :: Glyph+ , freeGlyphSentinel :: Glyph+ }+ deriving (Show)++instance Storable GlyphStorage where+ alignment ~_ = #alignment kbts_glyph_storage+ sizeOf ~_ = #size kbts_glyph_storage+ peek ptr = do+ arena <- (#peek kbts_glyph_storage, Arena) ptr+ glyphSentinel <- (#peek kbts_glyph_storage, GlyphSentinel) ptr+ freeGlyphSentinel <- (#peek kbts_glyph_storage, FreeGlyphSentinel) ptr+ pure GlyphStorage{..}+ poke ptr GlyphStorage{..} = do+ (#poke kbts_glyph_storage, Arena) ptr arena+ (#poke kbts_glyph_storage, GlyphSentinel) ptr glyphSentinel+ (#poke kbts_glyph_storage, FreeGlyphSentinel) ptr freeGlyphSentinel++data Glyph = Glyph+ { prev :: Ptr Glyph+ , next :: Ptr Glyph++ , codepoint :: Word32+ , id :: Word16 -- ^ Glyph index. This is what you want to use to query outline data.+ , uid :: Word16++ , userIdOrCodepointIndex :: Int+ {- ^ This field is kept and returned as-is throughout the shaping process.++ When you are using the context API, it contains a codepoint index always!+ To get the original user ID with the context API, you need to get the corresponding kbts_shape_codepoint+ with kbts_ShapeGetShapeCodepoint(Context, Glyph->UserIdOrCodepointIndex, ...);+ -}++ -- Used by GPOS+ , offsetX :: Int32+ , offsetY :: Int32+ , advanceX :: Int32+ , advanceY :: Int32++ , attachGlyph :: Ptr Glyph+ {- ^ Set by GPOS attachments++ Earlier on, we used to assume that, if a glyph had no advance, or had the MARK glyph class, then+ it could be handled as a mark in layout operations. This is inaccurate.+ Unicode makes a distinction between attached marks and standalone marks. For our purposes, attached+ marks are marks that have found a valid base character to attach to. In practice, this means that the+ font contains a valid display position/configuration for it in the current context.+ In contrast, standalone marks are marks that aren't attached to anything. Fonts may still have glyphs+ for them, in which case we want to display those just like regular glyphs that take up horizontal space+ on the line. When fonts don't have glyphs for them, they simply stay around as zero-width glyphs.+ Standalone marks have notably different behavior compared to attached marks, and so, once we start+ applying positioning features, it becomes worthwhile to track exactly which glyph has attached to which.+ -}++ , config :: Ptr () -- kbts_glyph_config *Config;++ , decomposition :: Word64++ , classes :: Word32 -- kbts_glyph_classes Classes;+ , flags :: GlyphFlags -- kbts_glyph_flags Flags;+ , parentInfo :: Word32++ , ligatureUid :: Word16+ {- ^ This is set by GSUB and used by GPOS.+ A 0-index means that we should attach to the last component in the ligature.++ From the Microsoft docs:+ To correctly access the subtables, the client must keep track of the component associated with the mark.++ For a given mark assigned to a particular class, the appropriate base attachment point is determined by which+ ligature component the mark is associated with. This is dependent on the original character string and subsequent+ character- or glyph-sequence processing, not the font data alone. While a text-layout client is performing any+ character-based preprocessing or any glyph-substitution operations using the GSUB table, the text-layout client+ must keep track of associations of marks to particular ligature-glyph components.+ -}++ , ligatureComponentIndexPlusOne :: Word16+ , ligatureComponentCount :: Word16++ , joiningFeature :: UnicodeJoiningFeature+ -- ^ Set in GSUB and used in GPOS, for STCH.++ -- Unicode properties filled in by CodepointToGlyph.+ , joiningType :: UnicodeJoiningType+ , unicodeFlags :: Word8+ , syllabicClass :: Word8+ , syllabicPosition :: Word8+ , useClass :: Word8+ , combiningClass :: Word8++ , markOrdering :: Word8 -- ^ Only used temporarily in NORMALIZE for Arabic mark reordering.+ }+ deriving (Show)++instance Storable Glyph where+ alignment ~_ = #alignment kbts_glyph+ sizeOf ~_ = #size kbts_glyph++ peek ptr = do+ prev <- (#peek kbts_glyph, Prev) ptr+ next <- (#peek kbts_glyph, Next) ptr+ codepoint <- (#peek kbts_glyph, Codepoint) ptr+ id <- (#peek kbts_glyph, Id) ptr+ uid <- (#peek kbts_glyph, Uid) ptr+ userIdOrCodepointIndex <- fromIntegral @CInt <$> (#peek kbts_glyph, UserIdOrCodepointIndex) ptr+ offsetX <- (#peek kbts_glyph, OffsetX) ptr+ offsetY <- (#peek kbts_glyph, OffsetY) ptr+ advanceX <- (#peek kbts_glyph, AdvanceX) ptr+ advanceY <- (#peek kbts_glyph, AdvanceY) ptr+ attachGlyph <- (#peek kbts_glyph, AttachGlyph) ptr+ config <- (#peek kbts_glyph, Config) ptr+ decomposition <- (#peek kbts_glyph, Decomposition) ptr+ classes <- (#peek kbts_glyph, Classes) ptr+ flags <- (#peek kbts_glyph, Flags) ptr+ parentInfo <- (#peek kbts_glyph, ParentInfo) ptr+ ligatureUid <- (#peek kbts_glyph, LigatureUid) ptr+ ligatureComponentIndexPlusOne <- (#peek kbts_glyph, LigatureComponentIndexPlusOne) ptr+ ligatureComponentCount <- (#peek kbts_glyph, LigatureComponentCount) ptr+ joiningFeature <- (#peek kbts_glyph, JoiningFeature) ptr+ joiningType <- (#peek kbts_glyph, JoiningType) ptr+ unicodeFlags <- (#peek kbts_glyph, UnicodeFlags) ptr+ syllabicClass <- (#peek kbts_glyph, SyllabicClass) ptr+ syllabicPosition <- (#peek kbts_glyph, SyllabicPosition) ptr+ useClass <- (#peek kbts_glyph, UseClass) ptr+ combiningClass <- (#peek kbts_glyph, CombiningClass) ptr+ markOrdering <- (#peek kbts_glyph, MarkOrdering) ptr+ pure Glyph{..}++ poke ptr Glyph{..} = do+ (#poke kbts_glyph, Prev) ptr prev+ (#poke kbts_glyph, Next) ptr next+ (#poke kbts_glyph, Codepoint) ptr codepoint+ (#poke kbts_glyph, Id) ptr id+ (#poke kbts_glyph, Uid) ptr uid+ (#poke kbts_glyph, UserIdOrCodepointIndex) ptr $ fromIntegral @_ @CInt userIdOrCodepointIndex+ (#poke kbts_glyph, OffsetX) ptr offsetX+ (#poke kbts_glyph, OffsetY) ptr offsetY+ (#poke kbts_glyph, AdvanceX) ptr advanceX+ (#poke kbts_glyph, AdvanceY) ptr advanceY+ (#poke kbts_glyph, AttachGlyph) ptr attachGlyph+ (#poke kbts_glyph, Config) ptr config+ (#poke kbts_glyph, Decomposition) ptr decomposition+ (#poke kbts_glyph, Classes) ptr classes+ (#poke kbts_glyph, Flags) ptr flags+ (#poke kbts_glyph, ParentInfo) ptr parentInfo+ (#poke kbts_glyph, LigatureUid) ptr ligatureUid+ (#poke kbts_glyph, LigatureComponentIndexPlusOne) ptr ligatureComponentIndexPlusOne+ (#poke kbts_glyph, LigatureComponentCount) ptr ligatureComponentCount+ (#poke kbts_glyph, JoiningFeature) ptr joiningFeature+ (#poke kbts_glyph, JoiningType) ptr joiningType+ (#poke kbts_glyph, UnicodeFlags) ptr unicodeFlags+ (#poke kbts_glyph, SyllabicClass) ptr syllabicClass+ (#poke kbts_glyph, SyllabicPosition) ptr syllabicPosition+ (#poke kbts_glyph, UseClass) ptr useClass+ (#poke kbts_glyph, CombiningClass) ptr combiningClass++data Codepoint = Codepoint+ { font :: Font -- ^ Only set when @(BreakFlags & KBTS_BREAK_FLAG_GRAPHEME) != 0@.+ , config :: Ptr () -- kbts_glyph_config*++ , codepoint :: Int+ , userId :: Int++ , breakFlags :: BreakFlags+ , script :: Script -- ^ Only set when @(BreakFlags & KBTS_BREAK_FLAG_SCRIPT) != 0@.+ , direction :: Direction -- ^ Only set when @(BreakFlags & KBTS_BREAK_FLAG_DIRECTION) != 0@.+ , paragraphDirection :: Direction -- ^ Only set when @(BreakFlags & KBTS_BREAK_FLAG_PARAGRAPH_DIRECTION) != 0@.+ }+ deriving (Show)++instance Storable Codepoint where+ alignment ~_ = #alignment kbts_shape_codepoint+ sizeOf ~_ = #size kbts_shape_codepoint++ peek ptr = do+ font <- (#peek kbts_shape_codepoint, Font) ptr+ config <- (#peek kbts_shape_codepoint, Config) ptr+ codepoint <- fromIntegral @CInt <$> (#peek kbts_shape_codepoint, Codepoint) ptr+ userId <- fromIntegral @CInt <$> (#peek kbts_shape_codepoint, UserId) ptr+ breakFlags <- (#peek kbts_shape_codepoint, BreakFlags) ptr+ script <- (#peek kbts_shape_codepoint, Script) ptr+ direction <- (#peek kbts_shape_codepoint, Direction) ptr+ paragraphDirection <- (#peek kbts_shape_codepoint, ParagraphDirection) ptr+ pure Codepoint{..}++ poke ptr Codepoint{..} = do+ (#poke kbts_shape_codepoint, Font) ptr font+ (#poke kbts_shape_codepoint, Codepoint) ptr $ fromIntegral @_ @CInt codepoint+ (#poke kbts_shape_codepoint, UserId) ptr $ fromIntegral @_ @CInt userId+ (#poke kbts_shape_codepoint, BreakFlags) ptr breakFlags+ (#poke kbts_shape_codepoint, Script) ptr script+ (#poke kbts_shape_codepoint, Direction) ptr direction+ (#poke kbts_shape_codepoint, ParagraphDirection) ptr paragraphDirection++data FeatureOverride = FeatureOverride+ { tag :: FeatureTag+ , value :: Int+ }+ deriving (Eq, Ord, Show)++instance Storable FeatureOverride where+ alignment ~_ = #alignment kbts_feature_override+ sizeOf ~_ = #size kbts_feature_override+ peek ptr = do+ tag <- peekByteOff ptr (#offset kbts_feature_override, Tag)+ value <- fromIntegral @CInt <$> peekByteOff ptr (#offset kbts_feature_override, Value)+ pure FeatureOverride{..}+ poke ptr FeatureOverride{..} = do+ pokeByteOff ptr (#offset kbts_feature_override, Tag) tag+ pokeByteOff ptr (#offset kbts_feature_override, Value) $ fromIntegral @_ @CInt value++data GlyphParent = GlyphParent+ { decomposition :: Word64+ , codepoint :: Word32+ }+ deriving (Eq, Ord, Show)++instance Storable GlyphParent where+ alignment ~_ = #alignment kbts_glyph_parent+ sizeOf ~_ = #size kbts_glyph_parent+ peek ptr = do+ decomposition <- (#peek kbts_glyph_parent, Decomposition) ptr+ codepoint <- (#peek kbts_glyph_parent, Codepoint) ptr+ pure GlyphParent{..}+ poke ptr GlyphParent{..} = do+ (#poke kbts_glyph_parent, Decomposition) ptr decomposition+ (#poke kbts_glyph_parent, Codepoint) ptr codepoint++pattern MAXIMUM_RECOMPOSITION_PARENTS :: Int+pattern MAXIMUM_RECOMPOSITION_PARENTS = #const KBTS_MAXIMUM_RECOMPOSITION_PARENTS++data FontCoverageTest = FontCoverageTest+ { font :: Font+ , baseCodepoint :: Word32++ , currentBaseError :: Int+ , error :: Int++ , baseParents :: Ptr GlyphParent -- ^ @kbts_glyph_parent BaseParents[KBTS_MAXIMUM_RECOMPOSITION_PARENTS];@+ , baseParentCount :: Word32+ }+ deriving (Show)++instance Storable FontCoverageTest where+ alignment ~_ = #alignment kbts_font_coverage_test+ sizeOf ~_ = #size kbts_font_coverage_test+ peek ptr = do+ font <- (#peek kbts_font_coverage_test, Font) ptr+ baseCodepoint <- (#peek kbts_font_coverage_test, BaseCodepoint) ptr+ currentBaseError <- fromIntegral @CInt <$> (#peek kbts_font_coverage_test, CurrentBaseError) ptr+ error <- fromIntegral @CInt <$> (#peek kbts_font_coverage_test, Error) ptr+ baseParents <- (#peek kbts_font_coverage_test, BaseParents) ptr+ baseParentCount <- (#peek kbts_font_coverage_test, BaseParentCount) ptr+ pure FontCoverageTest{..}+ poke ptr FontCoverageTest{..} = do+ (#poke kbts_font_coverage_test, Font) ptr font+ (#poke kbts_font_coverage_test, BaseCodepoint) ptr baseCodepoint+ (#poke kbts_font_coverage_test, CurrentBaseError) ptr $ fromIntegral @_ @CInt currentBaseError+ (#poke kbts_font_coverage_test, Error) ptr $ fromIntegral @_ @CInt error+ (#poke kbts_font_coverage_test, BaseParents) ptr baseParents+ (#poke kbts_font_coverage_test, BaseParentCount) ptr baseParentCount++data Break = Break+ { position :: Int+ {- ^+ The break code mostly works in relative positions, but we convert to absolute positions for the user.+ That way, breaks can be trivially stored and compared and such and it just works.+ -}+ , flags :: BreakFlags+ , direction :: Direction -- ^ Only valid if 'KBTS_BREAK_FLAG_DIRECTION' is set.+ , paragraphDirection :: Direction -- ^ Only valid if 'KBTS_BREAK_FLAG_PARAGRAPH_DIRECTION' is set.+ , script :: Script -- ^ Only valid if 'KBTS_BREAK_FLAG_SCRIPT' is set.+ }+ deriving (Show, Eq)++instance Storable Break where+ alignment ~_ = #alignment kbts_break+ sizeOf ~_ = #size kbts_break+ peek ptr = do+ position <- fromIntegral @CInt <$> (#peek kbts_break, Position) ptr+ flags <- (#peek kbts_break, Flags) ptr+ direction <- (#peek kbts_break, Direction) ptr+ paragraphDirection <- (#peek kbts_break, ParagraphDirection) ptr+ script <- (#peek kbts_break, Script) ptr+ pure Break{..}+ poke ptr Break{..} = do+ (#poke kbts_break, Position) ptr $ fromIntegral @_ @CInt position+ (#poke kbts_break, Flags) ptr flags+ (#poke kbts_break, Direction) ptr direction+ (#poke kbts_break, ParagraphDirection) ptr paragraphDirection+ (#poke kbts_break, Script) ptr script
+ src/KB/Text/Shape/Font.hs view
@@ -0,0 +1,180 @@+module KB.Text.Shape.Font+ ( -- * Distillation+ extractBlob++ -- * Loading+ , FontData(..)+ , createFont+ , destroyFont++ -- * Using+ , withFontData+ , Handles.Font++ -- * Querying+ , getFontInfo+ , Info(..)++ -- ** Font metrics+ , emToCaps+ , capHeight+ , unitsPerEm++ -- * Loading internals+ , withLoader+ , loadFont+ , LoadFontResult(..)+ , placeBlob+ ) where++import Prelude hiding (id)+import Foreign++import Control.Monad (when, zipWithM)+import Data.ByteString (ByteString)+import Data.ByteString.Internal qualified as ByteString+import Data.ByteString.Unsafe qualified as ByteString+import Data.Maybe (catMaybes)+import Data.Text (Text)+import Data.Text.Foreign qualified as Text++import KB.Text.Shape.FFI.API.Direct qualified as ShapeDirect+import KB.Text.Shape.FFI.API.Other qualified as Other+import KB.Text.Shape.FFI.Flags qualified as Flags+import KB.Text.Shape.FFI.Enums qualified as Enums+import KB.Text.Shape.FFI.Handles qualified as Handles+import KB.Text.Shape.FFI.Structs qualified as Structs++-- | Extract and pre-process font data needed for shaping.+extractBlob+ :: ByteString -- ^ TTF font data+ -> Int -- ^ Font index (use 0 for the first/only font)+ -> IO ByteString -- ^ KBTS blob data+extractBlob fontData fontIndex =+ withLoader \font statePtr -> do+ loadFont fontData fontIndex font statePtr >>= \case+ Left err ->+ error $ show err+ Right LoadFontNeedsBlob{scratchSize, outputSize} ->+ placeBlob font statePtr scratchSize outputSize+ Right LoadFontReady ->+ pure fontData++createFont :: ByteString -> Int -> IO FontData+createFont fontSource fontIndex =+ withLoader \font statePtr -> do+ loadFont fontSource fontIndex font statePtr >>= \case+ Left err ->+ error $ show err+ Right LoadFontNeedsBlob{scratchSize, outputSize} -> do+ blobData <- placeBlob font statePtr scratchSize outputSize+ pure font{fontResources = [fontSource, blobData]}+ Right LoadFontReady ->+ pure font{fontResources = [fontSource]}++destroyFont :: FontData -> IO ()+destroyFont font = withFontData font ShapeDirect.kbts_FreeFont++-- | Haskell-owned font data+data FontData = FontData+ { fontData :: ForeignPtr Word8+ , fontResources :: [ByteString]+ }+ deriving (Eq, Show)++-- | Use the font handle from a loaded font+withFontData :: FontData -> (Handles.Font -> IO r) -> IO r+withFontData FontData{fontData} action = withForeignPtr fontData (action . Handles.Font . castPtr)++getFontInfo :: Handles.Font -> IO Info+getFontInfo font =+ alloca \fontInfoPtr -> do+ ShapeDirect.kbts_GetFontInfo font fontInfoPtr+ Structs.FontInfo{strings=stringsArray, ..} <- peek fontInfoPtr+ strings <- catMaybes <$> zipWithM loadStrings (zip [0..Enums.FONT_INFO_STRING_ID_COUNT - 1] stringsArray) stringLengths+ pure Info{..}+ where+ loadStrings (ix, ptr) = \case+ 0 -> pure Nothing+ len -> Just . (Enums.FontInfoStringId ix,) <$> Text.peekCStringLen (ptr, fromIntegral len)++data Info = Info+ { strings :: [(Enums.FontInfoStringId, Text)]+ , styleFlags :: Flags.FontStyleFlags+ , weight :: Enums.FontWeight+ , width :: Enums.FontWidth+ }+ deriving (Eq, Show)++{- | Scaling factor to go from font-specific Em units to a cap-height normalized units.++This results in more consistent font sizing when using multiple fonts.+You may even have a chance to align something vertically!+-}+{-# INLINE emToCaps #-}+emToCaps :: Fractional a => Handles.Font -> a+emToCaps font = unitsPerEm font / capHeight font++-- | Get the height of font's capital letters, in the font's logical units.+{-# INLINE capHeight #-}+capHeight :: Num a => Handles.Font -> a+capHeight = fromIntegral . Other.hs_GetCapHeight++-- | Get the font's "Em square" size, in the font's logical units.+{-# INLINE unitsPerEm #-}+unitsPerEm :: Num a => Handles.Font -> a+unitsPerEm = fromIntegral . Other.hs_GetUnitsPerEm++withLoader :: (FontData -> Ptr ShapeDirect.LoadFontState -> IO a) -> IO a+withLoader action = do+ fontData <- mallocForeignPtrBytes Handles.sizeOfFontData+ let font = FontData{fontData, fontResources = []}+ withFontData font \(Handles.Font fontPtr) ->+ fillBytes fontPtr 0x00 Handles.sizeOfFontData+ alloca \statePtr -> do+ fillBytes statePtr 0x00 $ sizeOf (undefined :: ShapeDirect.LoadFontState)+ action font statePtr++data LoadFontResult+ = LoadFontReady+ | LoadFontNeedsBlob { scratchSize :: Int, outputSize :: Int}++loadFont+ :: ByteString+ -> Int+ -> FontData+ -> Ptr ShapeDirect.LoadFontState+ -> IO (Either Enums.LoadFontError LoadFontResult)+loadFont ttfData fontIndex font statePtr =+ withFontData font \fontPtr ->+ alloca \scratchSizePtr ->+ alloca \outputSizePtr ->+ ByteString.unsafeUseAsCStringLen ttfData \(ttfDataPtr, ttfDataSize) -> do+ err <- ShapeDirect.kbts_LoadFont+ fontPtr+ statePtr+ (castPtr ttfDataPtr)+ (fromIntegral ttfDataSize)+ (fromIntegral fontIndex)+ scratchSizePtr+ outputSizePtr+ case err of+ Enums.LOAD_FONT_ERROR_NONE ->+ pure $ Right LoadFontReady+ Enums.LOAD_FONT_ERROR_NEED_TO_CREATE_BLOB -> do+ scratchSize <- peek scratchSizePtr+ outputSize <- peek outputSizePtr+ pure $ Right LoadFontNeedsBlob{..}+ _ ->+ pure $ Left err++placeBlob :: FontData -> Ptr ShapeDirect.LoadFontState -> Int -> Int -> IO ByteString+placeBlob font statePtr scratchSize outputSize =+ allocaBytes scratchSize \scratchPtr -> do+ outputData <- mallocForeignPtrBytes outputSize+ withForeignPtr outputData \outputPtr ->+ withFontData font \fontPtr -> do+ err <- ShapeDirect.kbts_PlaceBlob fontPtr statePtr scratchPtr (castPtr outputPtr)+ when (err /= Enums.LOAD_FONT_ERROR_NONE) $+ error $ show err+ pure $! ByteString.fromForeignPtr0 outputData outputSize
+ test/Spec.hs view
@@ -0,0 +1,230 @@+{-# LANGUAGE OverloadedRecordDot #-}++import Control.Monad+import Data.Char+import Foreign+import Prelude hiding (id)++import Control.Exception (bracket)+import Data.ByteString qualified as ByteString+import Data.Text (Text)+import Data.Text qualified as Text++import KB.Text.Shape.FFI.API.Direct qualified as ShapeDirect+import KB.Text.Shape.FFI.Allocator (Allocator)+import KB.Text.Shape.FFI.Allocator qualified as Allocator+import KB.Text.Shape.FFI.Enums qualified as Enums+import KB.Text.Shape.FFI.Handles qualified as Handles+import KB.Text.Shape.FFI.Iterators qualified as Iterators+import KB.Text.Shape.FFI.Structs qualified as Structs++import KB.Text.Shape qualified as TextShape+import KB.Text.Shape.Font qualified as Font++testFontTtf :: FilePath+testFontTtf = "test/Ubuntu-R.ttf"++testFontBlob :: FilePath+testFontBlob = "test/Ubuntu-R.kbts"++testText :: Text+testText = "Hello, ሰላም።, שלמלך, नमस्ते world!"++testCodepoints :: [Char]+testCodepoints = Text.unpack testText++main :: IO ()+main = do+ putStrLn "mainSimple"+ mainSimple+ putStrLn ""++ putStrLn "mainContext - ttf"+ ttfGlyphs <- mainContext testFontTtf+ putStrLn ""++ putStrLn "mainDistill"+ mainDistill+ putStrLn ""++ putStrLn "mainContext - blob"+ blobGlyphs <- mainContext testFontBlob+ putStrLn ""++ if ttfGlyphs == blobGlyphs then+ putStrLn "Context/Blob works"+ else+ error "Context/Blob didn't quite work"+ putStrLn ""++ putStrLn "mainAllocatorDirect - ttf"+ ttfGlyphsDirect <- mainAllocatorDirect testFontTtf 0+ putStrLn ""+ putStrLn "mainAllocatorDirect - blob"+ blobGlyphsDirect <- mainAllocatorDirect testFontBlob 0+ putStrLn ""++ if ttfGlyphsDirect == blobGlyphsDirect then+ putStrLn "Direct/Blob works"+ else+ error "Direct/Blob didn't quite work"++ mainFontInfo++mainSimple :: IO ()+mainSimple = do+ TextShape.withContext \ctx -> do+ _fallback <- TextShape.pushFontFromFile ctx testFontTtf 0+ _main <- TextShape.pushFontFromFile ctx testFontBlob 0+ results <- TextShape.run ctx do+ TextShape.text_ "A bunch of characters"+ TextShape.char_ '!'+ forM_ results \(run, glyphs) -> do+ forM_ glyphs \glyph ->+ print (run.font, glyph.id, glyph.gpos.advanceX)++mainContext :: FilePath -> IO [(TextShape.Run, [TextShape.Glyph])]+mainContext fontFile =+ TextShape.withContext \ctx -> do+ putStrLn $ "Loading font from " <> fontFile+ font <- TextShape.pushFontFromFile ctx fontFile 0+ 2 <- TextShape.pushFont ctx font -- used 2 times+ results <- TextShape.run ctx do+ TextShape.text_ testText+ TextShape.char_ '!'+ writeFile "test/runs-and-glyphs.dump" $ show results+ forM results \(run, glyphs) -> do+ print run+ (run,) <$> dumpGlyphs glyphs++dumpGlyphs :: [TextShape.Glyph] -> IO [TextShape.Glyph]+dumpGlyphs =+ mapM \g@TextShape.Glyph{codepoint, id=id, advanceX, codepointIndex} -> do+ putStrLn $ (if id == 0 then '-' else '+') : ' ' : codepoint : " | " <> show id <> ", " <> show advanceX <> " $" <> show codepointIndex+ pure g++mainAllocatorDirect :: FilePath -> Int -> IO [TextShape.Glyph]+mainAllocatorDirect fontFile fontIndex = do+ fontData <- ByteString.readFile fontFile+ font <- Font.createFont fontData fontIndex+ glyphs <- oneshot font 42 testCodepoints+ Font.destroyFont font+ dumpGlyphs glyphs++oneshot :: Font.FontData -> Int -> [Char] -> IO [TextShape.Glyph]+oneshot fontData userId codepoints =+ Font.withFontData fontData \font ->+ withShapeConfig font script language \shapeConfig ->+ withGlyphStorage \glyphStoragePtr -> do+ withGlyphConfig \glyphConfig ->+ pushCodepoints font glyphStoragePtr glyphConfig userId codepoints+ shapeDirect shapeConfig glyphStoragePtr+ where+ script = Enums.SCRIPT_DONT_KNOW+ language = Enums.LANGUAGE_DONT_KNOW++withShapeConfig font script language =+ bracket+ (ShapeDirect.kbts_CreateShapeConfig font script language nullFunPtr nullPtr)+ ShapeDirect.kbts_DestroyShapeConfig++withGlyphStorage :: (Ptr Structs.GlyphStorage -> IO b) -> IO b+withGlyphStorage action = alloca @Structs.GlyphStorage \ptr -> do+ fillBytes ptr 0 (sizeOf (undefined :: Structs.GlyphStorage))+ action ptr++withGlyphConfig :: (Handles.GlyphConfig -> IO c) -> IO c+withGlyphConfig =+ bracket+ (ShapeDirect.kbts_CreateGlyphConfig nullPtr 0 nullFunPtr nullPtr)+ ShapeDirect.kbts_DestroyGlyphConfig++pushCodepoints :: (Foldable t, Integral a) => TextShape.Font -> Ptr Structs.GlyphStorage -> Handles.GlyphConfig -> a -> t Char -> IO ()+pushCodepoints font glyphStoragePtr glyphConfig userId = mapM_ \codepoint ->+ ShapeDirect.kbts_PushGlyph+ glyphStoragePtr+ font+ (fromIntegral $ ord codepoint)+ glyphConfig+ (fromIntegral userId)++shapeDirect :: Handles.ShapeConfig -> Ptr Structs.GlyphStorage -> IO [TextShape.Glyph]+shapeDirect shapeConfig glyphStoragePtr =+ alloca \glyphItPtr -> do+ !err <- ShapeDirect.kbts_ShapeDirect+ shapeConfig+ glyphStoragePtr+ Enums.DIRECTION_DONT_KNOW+ nullFunPtr+ nullPtr+ glyphItPtr+ when (err /= Enums.SHAPE_ERROR_NONE) $+ error $ show err+ alloca \glyphOutPtr ->+ iterateGlyphs glyphOutPtr glyphItPtr++mainDistill :: IO ()+mainDistill = do+ ttfData <- ByteString.readFile testFontTtf+ putStrLn $ "Distilling " <> show (ByteString.length ttfData `div` 1024) <> "Kb of TTF"+ blobData <- Font.extractBlob ttfData 0+ putStrLn $ "Distilled into " <> show (ByteString.length blobData `div` 1024) <> "Kb blob"+ ByteString.writeFile testFontBlob blobData++mainFontInfo :: IO ()+mainFontInfo =+ TextShape.withContext \ctx -> do+ putStrLn "TTF:"+ ttf <- TextShape.pushFontFromFile ctx testFontTtf 0+ Font.getFontInfo ttf >>= print+ putStrLn "Blob:"+ blob <- TextShape.pushFontFromFile ctx testFontBlob 0+ Font.getFontInfo blob >>= print+ putStrLn $ "Units per em: " <> show (Font.unitsPerEm blob)+ putStrLn $ "Cap height: " <> show (Font.capHeight blob)+ putStrLn $ "em2caps factor: " <> show (Font.emToCaps blob :: Float)++-- some copypasta from unexported parts++iterateGlyphs :: Ptr (Ptr Structs.Glyph) -> Ptr Structs.GlyphIterator -> IO [TextShape.Glyph]+iterateGlyphs glyphOutPtr it = stepWhile step fetch+ where+ step = (/= 0) <$> Iterators.kbts_GlyphIteratorNext it glyphOutPtr+ fetch = do+ peek glyphOutPtr >>= peek >>= TextShape.stripGlyph++stepWhile :: Monad m => m Bool -> m a -> m [a]+stepWhile step fetch = do+ result <- step+ if result then do+ x <- fetch+ (x :) <$> stepWhile step fetch+ else+ pure []++------++_debugAllocator :: Allocator+_debugAllocator = hallocator opAllocate opFree+ where+ opAllocate size = do+ putStrLn $ "debugAllocator: request for " <> show size+ callocBytes size+ opFree ptr = do+ putStrLn $ "debugAllocator: release " <> show ptr+ free ptr++hallocator+ :: (Int -> IO (Ptr ()))+ -> (Ptr () -> IO ())+ -> Allocator+hallocator opAllocate opFree adPtr opPtr = do+ op <- peek opPtr+ case op.kind of+ Allocator.OP_KIND_ALLOCATE -> do+ ptr <- opAllocate (fromIntegral op.size)+ poke opPtr op{Allocator.pointer=ptr} -- Ugh...+ Allocator.OP_KIND_FREE ->+ opFree op.pointer+ _huh ->+ error . mappend "Allocator.OP_KIND_???: " $ show (adPtr, op)