From e63c946116100b3ce68d3acef641aa94a73a4c45 Mon Sep 17 00:00:00 2001 From: agra Date: Mon, 2 Mar 2026 19:47:25 +0200 Subject: [PATCH] ... --- .gitignore | 3 +- assets/fonts/default.ttf | Bin 0 -> 773236 bytes goldens/last_frame.png | Bin 20961 -> 25526 bytes goldens/test_after_drag.png | Bin 0 -> 22976 bytes main.sx | 253 +- modules | 1 + ui/animation.sx | 108 + ui/button.sx | 33 +- ui/events.sx | 111 +- ui/font.sx | 104 + ui/gesture.sx | 128 + ui/image.sx | 36 + ui/label.sx | 10 +- ui/modifier.sx | 296 + ui/pipeline.sx | 10 +- ui/renderer.sx | 215 +- ui/scroll_view.sx | 148 + ui/stacks.sx | 6 +- ui/state.sx | 59 + ui/types.sx | 9 + ui/view.sx | 9 +- vendors/file_utils/file_utils.c | 14 + vendors/file_utils/file_utils.h | 6 + vendors/kb_text_shape/kb/LICENSE | 19 + vendors/kb_text_shape/kb/README.md | 70 + vendors/kb_text_shape/kb/images/arabic.png | Bin 0 -> 9350 bytes .../kb_text_shape/kb/images/gunjala_gondi.png | Bin 0 -> 11908 bytes vendors/kb_text_shape/kb/images/hindi.png | Bin 0 -> 4846 bytes vendors/kb_text_shape/kb/images/khmer.png | Bin 0 -> 4647 bytes vendors/kb_text_shape/kb/images/myanmar.png | Bin 0 -> 8670 bytes vendors/kb_text_shape/kb/images/smallcaps.png | Bin 0 -> 4576 bytes vendors/kb_text_shape/kb/kb_text_shape.h | 30737 ++++++++++++++++ vendors/kb_text_shape/kb_text_shape_impl.c | 2 + 33 files changed, 32185 insertions(+), 202 deletions(-) create mode 100644 assets/fonts/default.ttf create mode 100644 goldens/test_after_drag.png create mode 120000 modules create mode 100644 ui/animation.sx create mode 100644 ui/font.sx create mode 100644 ui/gesture.sx create mode 100644 ui/image.sx create mode 100644 ui/modifier.sx create mode 100644 ui/scroll_view.sx create mode 100644 ui/state.sx create mode 100644 vendors/file_utils/file_utils.c create mode 100644 vendors/file_utils/file_utils.h create mode 100644 vendors/kb_text_shape/kb/LICENSE create mode 100644 vendors/kb_text_shape/kb/README.md create mode 100644 vendors/kb_text_shape/kb/images/arabic.png create mode 100644 vendors/kb_text_shape/kb/images/gunjala_gondi.png create mode 100644 vendors/kb_text_shape/kb/images/hindi.png create mode 100644 vendors/kb_text_shape/kb/images/khmer.png create mode 100644 vendors/kb_text_shape/kb/images/myanmar.png create mode 100644 vendors/kb_text_shape/kb/images/smallcaps.png create mode 100644 vendors/kb_text_shape/kb/kb_text_shape.h create mode 100644 vendors/kb_text_shape/kb_text_shape_impl.c diff --git a/.gitignore b/.gitignore index 8a74dc1..828cb9a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ modules/ -.sx-cache \ No newline at end of file +.sx-cache +sx-out/ \ No newline at end of file diff --git a/assets/fonts/default.ttf b/assets/fonts/default.ttf new file mode 100644 index 0000000000000000000000000000000000000000..ab68fb197d4479b3b6dec6e85bd5cbaf433a87c5 GIT binary patch literal 773236 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
  • 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 literal 20961 zcmeHPYg7~07M_HF0TUU)N{C8`52~#dl!zz-k!VoM%ld8=qjGhsR()4GvjoxU^9pX0r_oBgsbAf?~rP9@f zs3!)Uv@ihTd`nuj^q*r3(WEt^t{1_wl`}%tG?cCM8vS^;u~5DT(TsFEm5geoEt6v&VW z4xJF~v>cdm0vlu*;UISmjaLpUK-P^Sgky_Hl1Tu1j14tTWVxrS{9lBY5N&1Sdfq}P zg27500^DFP=>h~hY$7;I36WU*0j_6aVB0k(h+uhY`p2n1vznOrS+(V+d>< ziL>D*AscWbSrHm3&mAYjVn7B!20#Wt217*n^CN?(NgJA(As_BTlqq0g#h6hv^={03 z@q1E_ruuQOim((hZWR4Fu{VZgOR2_8sU)##^cHFOW#3VB!T^FP%iLa_J^EqNlt|y$ zjzis@NF-rcGbVDSa+~rp>G0RJ{$0qyH@!X`%g?$i zga@?snd4%}Wh&)#@^R9_>h~rg#4G?)=48WvrZ1bzHk$yS}zA z0?qeh))B@PIhz|q6&T>D>%&SZ|eGj z5v13M3`r6jlAp1}aW%>qSHC9|KYs|Um6DppU zEF9gJJkD_-%O2$Knw0&us_rL!FFgGt^xg#aOy? z%znms1EYe?UyR6%&t{Ic;)Q&A=bmVsH8h4&gs!HFt|l)MI`LEo}CWv)xqP%ih}Ele*8Pd`-xr=fZQdkIUP5F;tP) z@q||~qLkI~8~iFBtHL(uw1?MoXeKAXq1XiC6Ys@O&7BUsGmvVBJ(xJZZQ=~wLssB9 z3O9f&+TWHi!KZ}oGpt@^vnA-MqA<7cW`V++>4zclVZalWP>c#041Kt!^M(3bmT;vM z)tzpuQ3*-wevUtsq_#RX@&(;1_J(Tmd(}@Rg_1&Akh~k=I3+7!O@1qis!$xK~DWp1CjxbYt=Mb7m2LoVdY zg_3`?PnPVeV4&eunilChQ)@`g(W`2AIMhTedirofU4+a1K=~u&W)gITacuk*igt|6 zvfG>er8llHgB@@>(P#!|yck=8)Q_*}_F8rE|bVEG&t)OM4OyvyC4P~ow* zM6Jy~b8E9lWj7;uo}3NYlET6vwQbmA2K}&s9HjY12>xv7ihC$=zkSx@O*`(CA%Dl7 zor3YEu3llHaX-ai-*gHrDMqL=G2{^{>bQ+$;Y&gy9=`Me^LY@H98gG`EsvjS;El+c ze5#J_=9i+3;iT`wo_gFB|+bYyHu1 zP5TS9LCMAH+LW+B0I99RPC{z>y1d$Qb!bq|h1eUds8(ev|6-73*YS@{WxC>3YzGYm z?49P$xHxscmFEyo$8lD*hz1+r{Gsteg|gD0MiaX0db-++ zr8(#Fh5C}QUbMK?x>L7WwWy(HZ|IwA_8ijOR|r>Y&rMGsh7aDAt(fS3!E4r1zjP+y z#=S-dyz<$xa$squc^}>&sC*tAB8U=GQ`d8{%=N9W=~OhuxYMEdwI`bZeT|@ OLJQ`F%sn3<*z-R?wuhzw diff --git a/goldens/test_after_drag.png b/goldens/test_after_drag.png new file mode 100644 index 0000000000000000000000000000000000000000..acd29dfed2d8f81bd199610ac75870941469cddd GIT binary patch literal 22976 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 cwO~N>3d1)`>Rf%G$;`lpzx~~z>% literal 0 HcmV?d00001 diff --git a/main.sx b/main.sx index a6954c5..5ce92ce 100644 --- a/main.sx +++ b/main.sx @@ -1,13 +1,65 @@ #import "modules/std.sx"; +#import "modules/compiler.sx"; #import "modules/sdl3.sx"; #import "modules/opengl.sx"; #import "modules/math"; #import "modules/stb.sx"; +#import "modules/stb_truetype.sx"; #import "ui"; +configure_build :: () { + opts := build_options(); + inline if OS == { + + case .wasm: { + inline if POINTER_SIZE == 4 { + opts.set_output_path("sx-out/wasm32/game.html"); + } else { + opts.set_output_path("sx-out/wasm64/game.html"); + } + + opts.add_link_flag("-sUSE_SDL=3"); + opts.add_link_flag("-sMAX_WEBGL_VERSION=2"); + opts.add_link_flag("-sFULL_ES3=1"); + opts.add_link_flag("--preload-file assets"); + opts.add_link_flag("-sALLOW_MEMORY_GROWTH=1"); + } + case .macos: { + opts.set_output_path("sx-out/macos/game"); + } + } +} +#run configure_build(); + +libc :: #library "c"; +emscripten_set_main_loop :: (func: *void, fps: s32, sim_infinite: s32) #foreign libc; + WIDTH :f32: 800; HEIGHT :f32: 600; +// --- Frame state (globals for emscripten callback) --- +g_window : *void = ---; +g_pipeline : *UIPipeline = ---; +g_running : bool = true; + +load_texture :: (path: [:0]u8) -> u32 { + w : s32 = 0; + h : s32 = 0; + ch : s32 = 0; + pixels := stbi_load(path, @w, @h, @ch, 4); + if xx pixels == 0 { return 0; } + + tex : u32 = 0; + glGenTextures(1, @tex); + glBindTexture(GL_TEXTURE_2D, tex); + glTexImage2D(GL_TEXTURE_2D, 0, xx GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, xx GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, xx GL_LINEAR); + + stbi_image_free(pixels); + tex; +} + save_snapshot :: (path: [:0]u8, w: s32, h: s32) { stride : s64 = w * 4; buf_size : s64 = stride * h; @@ -32,13 +84,114 @@ save_snapshot :: (path: [:0]u8, w: s32, h: s32) { out("\n"); } +run_ui_tests :: (pipeline: *UIPipeline) { + // Do a layout pass first so frames are computed + glClearColor(0.12, 0.12, 0.15, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + pipeline.tick(); + + // Button "Click Me" is roughly at center x=400, y=165 based on golden + btn_x : f32 = 400.0; + btn_y : f32 = 165.0; + btn_pos := Point.{ x = btn_x, y = btn_y }; + // Empty area below the rects + empty_x : f32 = 400.0; + empty_y : f32 = 500.0; + + // --- Test 1: Click button (no drag) --- + out("=== Test 1: button click ===\n"); + out("expect: Button tapped!\n"); + e :Event = .mouse_down(MouseButtonData.{ position = btn_pos, button = .left }); + pipeline.dispatch_event(@e); + e = .mouse_up(MouseButtonData.{ position = btn_pos, button = .left }); + pipeline.dispatch_event(@e); + out("=== end test 1 ===\n\n"); + + // --- Test 2: Drag from button area (should scroll, NOT tap) --- + out("=== Test 2: drag from button ===\n"); + out("expect: NO Button tapped, scroll should move\n"); + e = .mouse_down(MouseButtonData.{ position = btn_pos, button = .left }); + pipeline.dispatch_event(@e); + // Move down 50px in steps (exceeds 4px threshold) + i : s32 = 1; + while i <= 10 { + e = .mouse_moved(MouseMotionData.{ + position = Point.{ x = btn_x, y = btn_y + xx i * 5.0 }, + delta = Point.{ x = 0.0, y = 5.0 } + }); + pipeline.dispatch_event(@e); + i += 1; + } + e = .mouse_up(MouseButtonData.{ position = Point.{ x = btn_x, y = btn_y + 50.0 }, button = .left }); + pipeline.dispatch_event(@e); + out("=== end test 2 ===\n\n"); + + // --- Test 3: Drag from empty area (should scroll) --- + out("=== Test 3: drag from empty area ===\n"); + out("expect: scroll should move\n"); + e = .mouse_down(MouseButtonData.{ position = Point.{ x = empty_x, y = empty_y }, button = .left }); + pipeline.dispatch_event(@e); + i = 1; + while i <= 10 { + e = .mouse_moved(MouseMotionData.{ + position = Point.{ x = empty_x, y = empty_y - xx i * 5.0 }, + delta = Point.{ x = 0.0, y = 0.0 - 5.0 } + }); + pipeline.dispatch_event(@e); + i += 1; + } + e = .mouse_up(MouseButtonData.{ position = Point.{ x = empty_x, y = empty_y - 50.0 }, button = .left }); + pipeline.dispatch_event(@e); + out("=== end test 3 ===\n\n"); + + // Render after tests and save snapshot to see scrolled state + glClear(GL_COLOR_BUFFER_BIT); + pipeline.tick(); + save_snapshot("goldens/test_after_drag.png", xx WIDTH, xx HEIGHT); +} + +// One frame of the main loop — called repeatedly by emscripten or desktop while-loop +frame :: () { + sdl_event : SDL_Event = .none; + while SDL_PollEvent(sdl_event) { + print("SDL event: {}\n", sdl_event.tag); + + if sdl_event == { + case .quit: { g_running = false; } + case .key_up: (e) { + if e.key == { case .escape: { g_running = false; } } + } + } + + ui_event := translate_sdl_event(@sdl_event); + if ui_event != .none { + print(" ui event dispatched\n"); + g_pipeline.*.dispatch_event(@ui_event); + } else { + print(" -> .none\n"); + } + } + + glClearColor(0.12, 0.12, 0.15, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + + g_pipeline.*.tick(); + + SDL_GL_SwapWindow(g_window); +} + main :: () -> void { SDL_Init(SDL_INIT_VIDEO); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); + inline if OS == .wasm { + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); + } else { + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); + } SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); @@ -47,73 +200,55 @@ main :: () -> void { SDL_GL_MakeCurrent(window, gl_ctx); SDL_GL_SetSwapInterval(1); - load_gl(SDL_GL_GetProcAddress); - load_gl_ui(SDL_GL_GetProcAddress); + load_gl(xx SDL_GL_GetProcAddress); // --- Build UI --- pipeline : UIPipeline = ---; pipeline.init(WIDTH, HEIGHT); + pipeline.init_font("assets/fonts/default.ttf", 32.0); - // Create a simple layout: VStack with colored rects and a button - root := VStack.{ spacing = 10.0, alignment = .center }; + scroll_content := VStack.{ spacing = 10.0, alignment = .center } { + self.add( + Label.{ text = "Hello, SX!", font_size = 24.0, color = COLOR_WHITE } + |> padding(EdgeInsets.all(8.0)) + ); + self.add( + RectView.{ color = COLOR_YELLOW, preferred_height = 80.0, corner_radius = 8.0 } + |> padding(EdgeInsets.all(8.0)) + |> on_tap(closure(() { out("Yellow tapped!\n"); })) + ); + self.add( + Button.{ label = "Click Me", font_size = 14.0, style = ButtonStyle.default(), on_tap = closure(() { out("Button tapped!\n"); }) } + ); + self.add(HStack.{ spacing = 10.0, alignment = .center } { + self.add(RectView.{ color = COLOR_RED, preferred_width = 200.0, preferred_height = 300.0, corner_radius = 4.0 }); + self.add(RectView.{ color = COLOR_GREEN, preferred_width = 200.0, preferred_height = 300.0, corner_radius = 4.0 }); + }); + self.add( + RectView.{ color = COLOR_DARK_GRAY, preferred_height = 60.0 } + |> padding(EdgeInsets.symmetric(16.0, 8.0)) + |> background(COLOR_BLUE, 8.0) + ); + self.add(RectView.{ color = COLOR_ORANGE, preferred_height = 120.0, corner_radius = 12.0 }); + self.add(RectView.{ color = COLOR_GRAY, preferred_height = 200.0, corner_radius = 8.0 }); + }; - header := RectView.{ color = COLOR_YELLOW, preferred_height = 80.0, corner_radius = 8.0 }; - root.add(xx header); + root := ScrollView.{ child = ViewChild.{ view = scroll_content }, axes = .vertical }; + pipeline.set_root(root); - btn := Button.{ label = "Click Me", font_size = 14.0, style = ButtonStyle.default(), on_tap = null }; - root.add(xx btn); - - body := HStack.{ spacing = 10.0, alignment = .center }; - - left := RectView.{ color = COLOR_RED, preferred_width = 200.0, preferred_height = 300.0, corner_radius = 4.0 }; - body.add(xx left); - - right := RectView.{ color = COLOR_GREEN, preferred_width = 200.0, preferred_height = 300.0, corner_radius = 4.0 }; - body.add(xx right); - - root.add(xx body); - - footer := RectView.{ color = COLOR_DARK_GRAY, preferred_height = 60.0 }; - root.add(xx footer); - - pipeline.set_root(xx root); + // Store state in globals for frame callback + g_window = xx window; + g_pipeline = @pipeline; // --- Main loop --- - running := true; - sdl_event : SDL_Event = .none; - - while running { - while SDL_PollEvent(sdl_event) { - if sdl_event == { - case .quit: running = false; - case .key_up: (e) { - if e.key == { - case .escape: running = false; - } - } - } - - // Forward to UI - ui_event := translate_sdl_event(@sdl_event); - if ui_event.type != .none { - pipeline.dispatch_event(@ui_event); - } + inline if OS == .wasm { + emscripten_set_main_loop(xx frame, 0, 1); + } else { + while g_running { + frame(); } - - glClearColor(0.12, 0.12, 0.15, 1.0); - glClear(GL_COLOR_BUFFER_BIT); - - pipeline.tick(); - - SDL_GL_SwapWindow(window); } - // Re-render one frame for snapshot (back buffer is stale after swap) - glClearColor(0.12, 0.12, 0.15, 1.0); - glClear(GL_COLOR_BUFFER_BIT); - pipeline.tick(); - save_snapshot("goldens/last_frame.png", xx WIDTH, xx HEIGHT); - SDL_GL_DestroyContext(gl_ctx); SDL_DestroyWindow(window); SDL_Quit(); diff --git a/modules b/modules new file mode 120000 index 0000000..43a2b96 --- /dev/null +++ b/modules @@ -0,0 +1 @@ +/Users/agra/swipelab/sx/examples/modules \ No newline at end of file diff --git a/ui/animation.sx b/ui/animation.sx new file mode 100644 index 0000000..fcb33cd --- /dev/null +++ b/ui/animation.sx @@ -0,0 +1,108 @@ +#import "modules/std.sx"; +#import "modules/math"; + +// --- Easing Functions --- + +ease_linear :: (t: f32) -> f32 { t; } +ease_in_quad :: (t: f32) -> f32 { t * t; } +ease_out_quad :: (t: f32) -> f32 { t * (2.0 - t); } +ease_in_out_quad :: (t: f32) -> f32 { + if t < 0.5 then 2.0 * t * t + else -1.0 + (4.0 - 2.0 * t) * t; +} +ease_out_cubic :: (t: f32) -> f32 { u := t - 1.0; u * u * u + 1.0; } + +// --- AnimatedFloat — duration-based --- + +AnimatedFloat :: struct { + current: f32; + from: f32; + to: f32; + elapsed: f32; + duration: f32; + easing: ?Closure(f32) -> f32; + active: bool; + + make :: (value: f32) -> AnimatedFloat { + AnimatedFloat.{ + current = value, + from = value, + to = value, + elapsed = 0.0, + duration = 0.0, + easing = null, + active = false + }; + } + + animate_to :: (self: *AnimatedFloat, target: f32, dur: f32, ease: Closure(f32) -> f32) { + self.from = self.current; + self.to = target; + self.elapsed = 0.0; + self.duration = dur; + self.easing = ease; + self.active = true; + } + + tick :: (self: *AnimatedFloat, dt: f32) { + if !self.active { return; } + self.elapsed += dt; + t := clamp(self.elapsed / self.duration, 0.0, 1.0); + eased := if ease := self.easing { ease(t); } else { t; }; + self.current = self.from + (self.to - self.from) * eased; + if t >= 1.0 { + self.current = self.to; + self.active = false; + } + } +} + +// --- SpringFloat — physics-based --- + +SpringFloat :: struct { + current: f32; + velocity: f32; + target: f32; + stiffness: f32; + damping: f32; + mass: f32; + threshold: f32; + + make :: (value: f32) -> SpringFloat { + SpringFloat.{ + current = value, + velocity = 0.0, + target = value, + stiffness = 200.0, + damping = 20.0, + mass = 1.0, + threshold = 0.01 + }; + } + + snappy :: (value: f32) -> SpringFloat { + SpringFloat.{ + current = value, + velocity = 0.0, + target = value, + stiffness = 300.0, + damping = 25.0, + mass = 1.0, + threshold = 0.01 + }; + } + + tick :: (self: *SpringFloat, dt: f32) { + if self.is_settled() { return; } + force := 0.0 - self.stiffness * (self.current - self.target); + damping_force := 0.0 - self.damping * self.velocity; + accel := (force + damping_force) / self.mass; + self.velocity += accel * dt; + self.current += self.velocity * dt; + } + + is_settled :: (self: *SpringFloat) -> bool { + abs(self.current - self.target) < self.threshold + and abs(self.velocity) < self.threshold; + } +} diff --git a/ui/button.sx b/ui/button.sx index 7537fd1..3f2d077 100644 --- a/ui/button.sx +++ b/ui/button.sx @@ -4,6 +4,7 @@ #import "ui/events.sx"; #import "ui/view.sx"; #import "ui/label.sx"; +#import "ui/font.sx"; ButtonStyle :: struct { background: Color; @@ -37,12 +38,10 @@ Button :: struct { impl View for Button { size_that_fits :: (self: *Button, proposal: ProposedSize) -> Size { - scale := self.font_size / GLYPH_HEIGHT_APPROX; - text_w := xx self.label.len * GLYPH_WIDTH_APPROX * scale; - text_h := self.font_size; + text_size := measure_text(self.label, self.font_size); Size.{ - width = text_w + self.style.padding.horizontal(), - height = text_h + self.style.padding.vertical() + width = text_size.width + self.style.padding.horizontal(), + height = text_size.height + self.style.padding.vertical() }; } @@ -56,31 +55,29 @@ impl View for Button { ctx.add_rounded_rect(frame, bg, self.style.corner_radius); // Text centered in frame - scale := self.font_size / GLYPH_HEIGHT_APPROX; - text_w := xx self.label.len * GLYPH_WIDTH_APPROX * scale; - text_h := self.font_size; - text_x := frame.origin.x + (frame.size.width - text_w) * 0.5; - text_y := frame.origin.y + (frame.size.height - text_h) * 0.5; - text_frame := Frame.make(text_x, text_y, text_w, text_h); + text_size := measure_text(self.label, self.font_size); + text_x := frame.origin.x + (frame.size.width - text_size.width) * 0.5; + text_y := frame.origin.y + (frame.size.height - text_size.height) * 0.5; + text_frame := Frame.make(text_x, text_y, text_size.width, text_size.height); ctx.add_text(text_frame, self.label, self.font_size, self.style.foreground); } handle_event :: (self: *Button, event: *Event, frame: Frame) -> bool { - if event.type == { - case .mouse_moved: { - self.hovered = frame.contains(event.position); + if event.* == { + case .mouse_moved: (d) { + self.hovered = frame.contains(d.position); return false; } - case .mouse_down: { - if frame.contains(event.position) { + case .mouse_down: (d) { + if frame.contains(d.position) { self.pressed = true; return true; } } - case .mouse_up: { + case .mouse_up: (d) { if self.pressed { self.pressed = false; - if frame.contains(event.position) { + if frame.contains(d.position) { if handler := self.on_tap { handler(); } diff --git a/ui/events.sx b/ui/events.sx index 4c27f1c..b8ef287 100644 --- a/ui/events.sx +++ b/ui/events.sx @@ -2,19 +2,6 @@ #import "modules/sdl3.sx"; #import "ui/types.sx"; -EventType :: enum { - none; - mouse_down; - mouse_up; - mouse_moved; - mouse_wheel; - key_down; - key_up; - text_input; - window_resize; - quit; -} - MouseButton :: enum { none; left; @@ -22,85 +9,89 @@ MouseButton :: enum { right; } -Event :: struct { - type: EventType; - position: Point; - delta: Point; - button: MouseButton; - key: u32; - text: string; - timestamp: u64; +MouseButtonData :: struct { position: Point; button: MouseButton; } +MouseMotionData :: struct { position: Point; delta: Point; } +MouseWheelData :: struct { position: Point; delta: Point; } +KeyData :: struct { key: u32; } +ResizeData :: struct { size: Size; } - make :: (type: EventType) -> Event { - e : Event = ---; - memset(@e, 0, size_of(Event)); - e.type = type; - e; +Event :: enum { + none; + quit; + mouse_down: MouseButtonData; + mouse_up: MouseButtonData; + mouse_moved: MouseMotionData; + mouse_wheel: MouseWheelData; + key_down: KeyData; + key_up: KeyData; + text_input: string; + window_resize: ResizeData; +} + +event_position :: (e: *Event) -> ?Point { + if e.* == { + case .mouse_down: (d) { return d.position; } + case .mouse_up: (d) { return d.position; } + case .mouse_moved: (d) { return d.position; } + case .mouse_wheel: (d) { return d.position; } } + null; } // Translate SDL_Event → our Event type translate_sdl_event :: (sdl: *SDL_Event) -> Event { if sdl.* == { case .quit: { - return Event.make(.quit); + return .quit; } case .key_down: (data) { - e := Event.make(.key_down); - e.key = xx data.key; - e.timestamp = data.timestamp; - return e; + return .key_down(KeyData.{ key = xx data.key }); } case .key_up: (data) { - e := Event.make(.key_up); - e.key = xx data.key; - e.timestamp = data.timestamp; - return e; + return .key_up(KeyData.{ key = xx data.key }); } case .mouse_motion: (data) { - e := Event.make(.mouse_moved); - e.position = Point.{ x = data.x, y = data.y }; - e.delta = Point.{ x = data.xrel, y = data.yrel }; - e.timestamp = data.timestamp; - return e; + return .mouse_moved(MouseMotionData.{ + position = Point.{ x = data.x, y = data.y }, + delta = Point.{ x = data.xrel, y = data.yrel } + }); } case .mouse_button_down: (data) { - e := Event.make(.mouse_down); - e.position = Point.{ x = data.x, y = data.y }; - e.button = if data.button == { + print(" mouse_down raw: x={} y={} btn={}\n", data.x, data.y, data.button); + btn :MouseButton = if data.button == { case 1: .left; case 2: .middle; case 3: .right; else: .none; }; - e.timestamp = data.timestamp; - return e; + return .mouse_down(MouseButtonData.{ + position = Point.{ x = data.x, y = data.y }, + button = btn + }); } case .mouse_button_up: (data) { - e := Event.make(.mouse_up); - e.position = Point.{ x = data.x, y = data.y }; - e.button = if data.button == { + btn :MouseButton = if data.button == { case 1: .left; case 2: .middle; case 3: .right; else: .none; }; - e.timestamp = data.timestamp; - return e; + return .mouse_up(MouseButtonData.{ + position = Point.{ x = data.x, y = data.y }, + button = btn + }); } case .mouse_wheel: (data) { - e := Event.make(.mouse_wheel); - e.delta = Point.{ x = data.x, y = data.y }; - e.position = Point.{ x = data.mouse_x, y = data.mouse_y }; - e.timestamp = data.timestamp; - return e; + return .mouse_wheel(MouseWheelData.{ + position = Point.{ x = data.mouse_x, y = data.mouse_y }, + delta = Point.{ x = data.x, y = data.y } + }); } case .window_resized: (data) { - e := Event.make(.window_resize); - e.position = Point.{ x = xx data.data1, y = xx data.data2 }; - e.timestamp = data.timestamp; - return e; + return .window_resize(ResizeData.{ + size = Size.{ width = xx data.data1, height = xx data.data2 } + }); } } - Event.make(.none); + .none; } diff --git a/ui/font.sx b/ui/font.sx new file mode 100644 index 0000000..32f8893 --- /dev/null +++ b/ui/font.sx @@ -0,0 +1,104 @@ +#import "modules/std.sx"; +#import "ui/types.sx"; + +FIRST_CHAR :s32: 32; +NUM_CHARS :s32: 96; +ATLAS_W :s32: 512; +ATLAS_H :s32: 512; + +// Matches stbtt_bakedchar memory layout +BakedChar :: struct { + x0, y0, x1, y1: u16; + xoff, yoff, xadvance: f32; +} + +// Matches stbtt_aligned_quad memory layout +AlignedQuad :: struct { + x0, y0, s0, t0: f32; + x1, y1, s1, t1: f32; +} + +FontAtlas :: struct { + texture_id: u32; + font_size: f32; + char_data: [*]BakedChar; + bitmap: [*]u8; + ascent: f32; + descent: f32; + line_height: f32; + + // Bake font glyphs into a bitmap. Call upload_texture() after GL is ready. + init :: (self: *FontAtlas, path: [:0]u8, size: f32) { + file_size : s32 = 0; + font_data := read_file_bytes(path, @file_size); + if xx font_data == 0 { + out("Failed to load font: "); + out(path); + out("\n"); + return; + } + + self.font_size = size; + + // Allocate baked char data (96 entries for ASCII 32..127) + self.char_data = xx context.allocator.alloc(xx NUM_CHARS * size_of(BakedChar)); + + // Bake font bitmap (512x512 single-channel alpha) + bitmap_size : s64 = xx ATLAS_W * xx ATLAS_H; + self.bitmap = xx context.allocator.alloc(bitmap_size); + stbtt_BakeFontBitmap(font_data, 0, size, self.bitmap, ATLAS_W, ATLAS_H, FIRST_CHAR, NUM_CHARS, xx self.char_data); + + // Get font vertical metrics + fontinfo : [256]u8 = ---; + stbtt_InitFont(xx @fontinfo, font_data, 0); + ascent_i : s32 = 0; + descent_i : s32 = 0; + linegap_i : s32 = 0; + stbtt_GetFontVMetrics(xx @fontinfo, @ascent_i, @descent_i, @linegap_i); + scale := stbtt_ScaleForPixelHeight(xx @fontinfo, size); + self.ascent = xx ascent_i * scale; + self.descent = xx descent_i * scale; + self.line_height = self.ascent - self.descent + xx linegap_i * scale; + + font_data_ptr : *void = xx font_data; + free(font_data_ptr); + + out("Font loaded: "); + out(path); + out("\n"); + } + + measure_text :: (self: *FontAtlas, text: string, font_size: f32) -> Size { + if self.char_data == null { return Size.zero(); } + scale := font_size / self.font_size; + xpos : f32 = 0.0; + ypos : f32 = 0.0; + q : AlignedQuad = ---; + i : s64 = 0; + while i < text.len { + ch : s32 = xx text[i]; + if ch >= FIRST_CHAR and ch < FIRST_CHAR + NUM_CHARS { + stbtt_GetBakedQuad(xx self.char_data, ATLAS_W, ATLAS_H, ch - FIRST_CHAR, @xpos, @ypos, xx @q, 1); + } + i += 1; + } + Size.{ width = xpos * scale, height = self.line_height * scale }; + } +} + +// Global font atlas pointer for views (Label, Button) to access +g_font : *FontAtlas = xx 0; + +set_global_font :: (font: *FontAtlas) { + g_font = font; +} + +// Convenience measurement function for views +measure_text :: (text: string, font_size: f32) -> Size { + if xx g_font == 0 { + // Fallback approximate measurement + scale := font_size / 16.0; + return Size.{ width = xx text.len * 8.0 * scale, height = font_size }; + } + g_font.measure_text(text, font_size); +} diff --git a/ui/gesture.sx b/ui/gesture.sx new file mode 100644 index 0000000..b4ebb11 --- /dev/null +++ b/ui/gesture.sx @@ -0,0 +1,128 @@ +#import "modules/std.sx"; +#import "modules/math"; +#import "ui/types.sx"; +#import "ui/events.sx"; + +GesturePhase :: enum { + possible; + began; + changed; + ended; + cancelled; + failed; +} + +// --- TapGesture --- + +TapValue :: struct { + location: Point; + count: s32; +} + +TapGesture :: struct { + count: s32; + on_tap: ?Closure(); + phase: GesturePhase; + tap_count: s32; + start_position: Point; + + TAP_THRESHOLD :f32: 10.0; + + handle_event :: (self: *TapGesture, event: *Event, frame: Frame) -> bool { + if event.* == { + case .mouse_down: (d) { + if frame.contains(d.position) { + self.phase = .began; + self.start_position = d.position; + return true; + } + } + case .mouse_moved: (d) { + if self.phase == .began { + if self.start_position.distance(d.position) > TapGesture.TAP_THRESHOLD { + self.phase = .failed; + } + } + } + case .mouse_up: (d) { + if self.phase == .began { + if frame.contains(d.position) { + self.tap_count += 1; + if self.tap_count >= self.count { + if handler := self.on_tap { handler(); } + self.tap_count = 0; + } + } + } + self.phase = .possible; + return true; + } + } + false; + } +} + +// --- DragGesture --- + +DragValue :: struct { + location: Point; + start_location: Point; + translation: Point; +} + +DragGesture :: struct { + min_distance: f32; + on_changed: ?Closure(DragValue); + on_ended: ?Closure(DragValue); + phase: GesturePhase; + start_location: Point; + current_location: Point; + + make_value :: (self: *DragGesture) -> DragValue { + DragValue.{ + location = self.current_location, + start_location = self.start_location, + translation = self.current_location.sub(self.start_location) + }; + } + + handle_event :: (self: *DragGesture, event: *Event, frame: Frame) -> bool { + if event.* == { + case .mouse_down: (d) { + if frame.contains(d.position) { + self.phase = .possible; + self.start_location = d.position; + self.current_location = d.position; + return true; + } + } + case .mouse_moved: (d) { + if self.phase == .possible { + self.current_location = d.position; + if self.start_location.distance(d.position) >= self.min_distance { + self.phase = .began; + if handler := self.on_changed { handler(self.make_value()); } + } + return true; + } + if self.phase == .began or self.phase == .changed { + self.current_location = d.position; + self.phase = .changed; + if handler := self.on_changed { handler(self.make_value()); } + return true; + } + } + case .mouse_up: (d) { + if self.phase == .began or self.phase == .changed { + self.current_location = d.position; + self.phase = .ended; + if handler := self.on_ended { handler(self.make_value()); } + self.phase = .possible; + return true; + } + self.phase = .possible; + } + } + false; + } +} diff --git a/ui/image.sx b/ui/image.sx new file mode 100644 index 0000000..0471954 --- /dev/null +++ b/ui/image.sx @@ -0,0 +1,36 @@ +#import "modules/std.sx"; +#import "ui/types.sx"; +#import "ui/render.sx"; +#import "ui/events.sx"; +#import "ui/view.sx"; + +ImageView :: struct { + texture_id: u32; + width: f32; + height: f32; + tint: Color; +} + +impl View for ImageView { + size_that_fits :: (self: *ImageView, proposal: ProposedSize) -> Size { + pw := proposal.width ?? self.width; + ph := proposal.height ?? self.height; + // Maintain aspect ratio: fit within proposal + aspect := self.width / self.height; + if pw / ph > aspect { + Size.{ width = ph * aspect, height = ph }; + } else { + Size.{ width = pw, height = pw / aspect }; + } + } + + layout :: (self: *ImageView, bounds: Frame) {} + + render :: (self: *ImageView, ctx: *RenderContext, frame: Frame) { + ctx.add_image(frame, self.texture_id); + } + + handle_event :: (self: *ImageView, event: *Event, frame: Frame) -> bool { + false; + } +} diff --git a/ui/label.sx b/ui/label.sx index cac3e00..3129c06 100644 --- a/ui/label.sx +++ b/ui/label.sx @@ -3,9 +3,7 @@ #import "ui/render.sx"; #import "ui/events.sx"; #import "ui/view.sx"; - -GLYPH_WIDTH_APPROX :f32: 8.0; -GLYPH_HEIGHT_APPROX :f32: 16.0; +#import "ui/font.sx"; Label :: struct { text: string; @@ -23,11 +21,7 @@ Label :: struct { impl View for Label { size_that_fits :: (self: *Label, proposal: ProposedSize) -> Size { - // Approximate: chars × avg glyph width, scaled by font size - scale := self.font_size / GLYPH_HEIGHT_APPROX; - w := xx self.text.len * GLYPH_WIDTH_APPROX * scale; - h := self.font_size; - Size.{ width = w, height = h }; + measure_text(self.text, self.font_size); } layout :: (self: *Label, bounds: Frame) { diff --git a/ui/modifier.sx b/ui/modifier.sx new file mode 100644 index 0000000..481f6c7 --- /dev/null +++ b/ui/modifier.sx @@ -0,0 +1,296 @@ +#import "modules/std.sx"; +#import "modules/math"; +#import "ui/types.sx"; +#import "ui/render.sx"; +#import "ui/events.sx"; +#import "ui/view.sx"; +#import "ui/gesture.sx"; + +// --- PaddingModifier --- + +PaddingModifier :: struct { + child: ViewChild; + insets: EdgeInsets; +} + +impl View for PaddingModifier { + size_that_fits :: (self: *PaddingModifier, proposal: ProposedSize) -> Size { + iw: ?f32 = null; + ih: ?f32 = null; + if w := proposal.width { iw = w - self.insets.horizontal(); } + if h := proposal.height { ih = h - self.insets.vertical(); } + inner := ProposedSize.{ width = iw, height = ih }; + child_size := self.child.view.size_that_fits(inner); + Size.{ + width = child_size.width + self.insets.horizontal(), + height = child_size.height + self.insets.vertical() + }; + } + + layout :: (self: *PaddingModifier, bounds: Frame) { + self.child.computed_frame = bounds.inset(self.insets); + self.child.view.layout(self.child.computed_frame); + } + + render :: (self: *PaddingModifier, ctx: *RenderContext, frame: Frame) { + self.child.view.render(ctx, self.child.computed_frame); + } + + handle_event :: (self: *PaddingModifier, event: *Event, frame: Frame) -> bool { + self.child.view.handle_event(event, self.child.computed_frame); + } +} + +// --- FrameModifier --- + +FrameModifier :: struct { + child: ViewChild; + width: ?f32; + height: ?f32; +} + +impl View for FrameModifier { + size_that_fits :: (self: *FrameModifier, proposal: ProposedSize) -> Size { + pw := self.width ?? proposal.width ?? 0.0; + ph := self.height ?? proposal.height ?? 0.0; + child_proposal := ProposedSize.{ width = pw, height = ph }; + child_size := self.child.view.size_that_fits(child_proposal); + Size.{ + width = self.width ?? child_size.width, + height = self.height ?? child_size.height + }; + } + + layout :: (self: *FrameModifier, bounds: Frame) { + child_size := self.child.view.size_that_fits(ProposedSize.{ + width = self.width ?? bounds.size.width, + height = self.height ?? bounds.size.height + }); + // Center child within bounds + cx := bounds.origin.x + (bounds.size.width - child_size.width) * 0.5; + cy := bounds.origin.y + (bounds.size.height - child_size.height) * 0.5; + self.child.computed_frame = Frame.make(cx, cy, child_size.width, child_size.height); + self.child.view.layout(self.child.computed_frame); + } + + render :: (self: *FrameModifier, ctx: *RenderContext, frame: Frame) { + self.child.view.render(ctx, self.child.computed_frame); + } + + handle_event :: (self: *FrameModifier, event: *Event, frame: Frame) -> bool { + self.child.view.handle_event(event, self.child.computed_frame); + } +} + +// --- BackgroundModifier --- + +BackgroundModifier :: struct { + child: ViewChild; + color: Color; + corner_radius: f32; +} + +impl View for BackgroundModifier { + size_that_fits :: (self: *BackgroundModifier, proposal: ProposedSize) -> Size { + self.child.view.size_that_fits(proposal); + } + + layout :: (self: *BackgroundModifier, bounds: Frame) { + self.child.computed_frame = bounds; + self.child.view.layout(bounds); + } + + render :: (self: *BackgroundModifier, ctx: *RenderContext, frame: Frame) { + if self.corner_radius > 0.0 { + ctx.add_rounded_rect(frame, self.color, self.corner_radius); + } else { + ctx.add_rect(frame, self.color); + } + self.child.view.render(ctx, self.child.computed_frame); + } + + handle_event :: (self: *BackgroundModifier, event: *Event, frame: Frame) -> bool { + self.child.view.handle_event(event, self.child.computed_frame); + } +} + +// --- OpacityModifier --- + +OpacityModifier :: struct { + child: ViewChild; + alpha: f32; +} + +impl View for OpacityModifier { + size_that_fits :: (self: *OpacityModifier, proposal: ProposedSize) -> Size { + self.child.view.size_that_fits(proposal); + } + + layout :: (self: *OpacityModifier, bounds: Frame) { + self.child.computed_frame = bounds; + self.child.view.layout(bounds); + } + + render :: (self: *OpacityModifier, ctx: *RenderContext, frame: Frame) { + prev := ctx.opacity; + ctx.push_opacity(self.alpha); + self.child.view.render(ctx, self.child.computed_frame); + ctx.pop_opacity(prev); + } + + handle_event :: (self: *OpacityModifier, event: *Event, frame: Frame) -> bool { + self.child.view.handle_event(event, self.child.computed_frame); + } +} + +// --- ClipModifier --- + +ClipModifier :: struct { + child: ViewChild; + corner_radius: f32; +} + +impl View for ClipModifier { + size_that_fits :: (self: *ClipModifier, proposal: ProposedSize) -> Size { + self.child.view.size_that_fits(proposal); + } + + layout :: (self: *ClipModifier, bounds: Frame) { + self.child.computed_frame = bounds; + self.child.view.layout(bounds); + } + + render :: (self: *ClipModifier, ctx: *RenderContext, frame: Frame) { + ctx.push_clip(frame); + self.child.view.render(ctx, self.child.computed_frame); + ctx.pop_clip(); + } + + handle_event :: (self: *ClipModifier, event: *Event, frame: Frame) -> bool { + self.child.view.handle_event(event, self.child.computed_frame); + } +} + +// --- HiddenModifier --- + +HiddenModifier :: struct { + child: ViewChild; + is_hidden: bool; +} + +impl View for HiddenModifier { + size_that_fits :: (self: *HiddenModifier, proposal: ProposedSize) -> Size { + if self.is_hidden { return Size.zero(); } + self.child.view.size_that_fits(proposal); + } + + layout :: (self: *HiddenModifier, bounds: Frame) { + if self.is_hidden { return; } + self.child.computed_frame = bounds; + self.child.view.layout(bounds); + } + + render :: (self: *HiddenModifier, ctx: *RenderContext, frame: Frame) { + if self.is_hidden { return; } + self.child.view.render(ctx, self.child.computed_frame); + } + + handle_event :: (self: *HiddenModifier, event: *Event, frame: Frame) -> bool { + if self.is_hidden { return false; } + self.child.view.handle_event(event, self.child.computed_frame); + } +} + +// --- TapGestureModifier --- + +TapGestureModifier :: struct { + child: ViewChild; + gesture: TapGesture; +} + +impl View for TapGestureModifier { + size_that_fits :: (self: *TapGestureModifier, proposal: ProposedSize) -> Size { + self.child.view.size_that_fits(proposal); + } + + layout :: (self: *TapGestureModifier, bounds: Frame) { + self.child.computed_frame = bounds; + self.child.view.layout(bounds); + } + + render :: (self: *TapGestureModifier, ctx: *RenderContext, frame: Frame) { + self.child.view.render(ctx, self.child.computed_frame); + } + + handle_event :: (self: *TapGestureModifier, event: *Event, frame: Frame) -> bool { + if self.gesture.handle_event(event, frame) { return true; } + self.child.view.handle_event(event, self.child.computed_frame); + } +} + +// --- DragGestureModifier --- + +DragGestureModifier :: struct { + child: ViewChild; + gesture: DragGesture; +} + +impl View for DragGestureModifier { + size_that_fits :: (self: *DragGestureModifier, proposal: ProposedSize) -> Size { + self.child.view.size_that_fits(proposal); + } + + layout :: (self: *DragGestureModifier, bounds: Frame) { + self.child.computed_frame = bounds; + self.child.view.layout(bounds); + } + + render :: (self: *DragGestureModifier, ctx: *RenderContext, frame: Frame) { + self.child.view.render(ctx, self.child.computed_frame); + } + + handle_event :: (self: *DragGestureModifier, event: *Event, frame: Frame) -> bool { + if self.gesture.handle_event(event, frame) { return true; } + self.child.view.handle_event(event, self.child.computed_frame); + } +} + +// --- Convenience functions --- + +padding :: (view: View, insets: EdgeInsets) -> PaddingModifier { + PaddingModifier.{ child = ViewChild.{ view = view }, insets = insets }; +} + +fixed_frame :: (view: View, width: ?f32, height: ?f32) -> FrameModifier { + FrameModifier.{ child = ViewChild.{ view = view }, width = width, height = height }; +} + +background :: (view: View, color: Color, corner_radius: f32) -> BackgroundModifier { + BackgroundModifier.{ child = ViewChild.{ view = view }, color = color, corner_radius = corner_radius }; +} + +with_opacity :: (view: View, alpha: f32) -> OpacityModifier { + OpacityModifier.{ child = ViewChild.{ view = view }, alpha = alpha }; +} + +clip :: (view: View, corner_radius: f32) -> ClipModifier { + ClipModifier.{ child = ViewChild.{ view = view }, corner_radius = corner_radius }; +} + +hidden :: (view: View, is_hidden: bool) -> HiddenModifier { + HiddenModifier.{ child = ViewChild.{ view = view }, is_hidden = is_hidden }; +} + +on_tap :: (view: View, handler: Closure()) -> TapGestureModifier { + TapGestureModifier.{ + child = ViewChild.{ view = view }, + gesture = TapGesture.{ count = 1, on_tap = handler } + }; +} + +on_drag :: (view: View, on_changed: ?Closure(DragValue), on_ended: ?Closure(DragValue)) -> DragGestureModifier { + DragGestureModifier.{ + child = ViewChild.{ view = view }, + gesture = DragGesture.{ min_distance = 10.0, on_changed = on_changed, on_ended = on_ended } + }; +} diff --git a/ui/pipeline.sx b/ui/pipeline.sx index 725b86b..0eb23ca 100644 --- a/ui/pipeline.sx +++ b/ui/pipeline.sx @@ -9,6 +9,7 @@ UIPipeline :: struct { renderer: UIRenderer; render_tree: RenderTree; + font: FontAtlas; screen_width: f32; screen_height: f32; root: ViewChild; @@ -22,8 +23,14 @@ UIPipeline :: struct { self.has_root = false; } + init_font :: (self: *UIPipeline, path: [:0]u8, size: f32) { + self.font.init(path, size); + upload_font_texture(@self.font); + set_global_font(@self.font); + } + set_root :: (self: *UIPipeline, view: View) { - self.root = ViewChild.make(view); + self.root = ViewChild.{ view = view }; self.has_root = true; } @@ -51,6 +58,7 @@ UIPipeline :: struct { origin = Point.zero(), size = root_size }; + print("tick: computed_frame=({},{},{},{})\n", self.root.computed_frame.origin.x, self.root.computed_frame.origin.y, self.root.computed_frame.size.width, self.root.computed_frame.size.height); self.root.view.layout(self.root.computed_frame); // Render to tree diff --git a/ui/renderer.sx b/ui/renderer.sx index 85dabd5..09150f9 100644 --- a/ui/renderer.sx +++ b/ui/renderer.sx @@ -1,4 +1,5 @@ #import "modules/std.sx"; +#import "modules/compiler.sx"; #import "modules/opengl.sx"; #import "modules/math"; #import "ui/types.sx"; @@ -14,17 +15,23 @@ UIRenderer :: struct { vbo: u32; shader: u32; proj_loc: s32; + tex_loc: s32; vertices: [*]f32; vertex_count: s64; screen_width: f32; screen_height: f32; white_texture: u32; + current_texture: u32; init :: (self: *UIRenderer) { - // Create shader - self.shader = create_program(UI_VERT_SRC, UI_FRAG_SRC); - + // Create shader (ES for WASM/WebGL2, Core for desktop) + inline if OS == .wasm { + self.shader = create_program(UI_VERT_SRC_ES, UI_FRAG_SRC_ES); + } else { + self.shader = create_program(UI_VERT_SRC_CORE, UI_FRAG_SRC_CORE); + } self.proj_loc = glGetUniformLocation(self.shader, "uProj"); + self.tex_loc = glGetUniformLocation(self.shader, "uTex"); // Allocate vertex buffer (CPU side) buf_size := MAX_UI_VERTICES * UI_VERTEX_BYTES; @@ -62,6 +69,14 @@ UIRenderer :: struct { self.screen_width = width; self.screen_height = height; self.vertex_count = 0; + self.current_texture = self.white_texture; + } + + bind_texture :: (self: *UIRenderer, tex: u32) { + if tex != self.current_texture { + self.flush(); + self.current_texture = tex; + } } // Emit a quad (2 triangles = 6 vertices) @@ -122,13 +137,14 @@ UIRenderer :: struct { self.push_quad(node.frame, node.fill_color, node.corner_radius, node.stroke_width); } case .text: { - // TODO: text rendering via glyph atlas - // For now, render a placeholder rect - self.push_quad(node.frame, node.text_color, 0.0, 0.0); + if xx g_font != 0 and g_font.char_data != null { + self.render_text(node); + } } case .image: { - // TODO: textured quad + self.bind_texture(node.texture_id); self.push_quad(node.frame, COLOR_WHITE, 0.0, 0.0); + self.bind_texture(self.white_texture); } case .clip_push: { self.flush(); @@ -160,6 +176,11 @@ UIRenderer :: struct { proj := Mat4.ortho(0.0, self.screen_width, self.screen_height, 0.0, -1.0, 1.0); glUniformMatrix4fv(self.proj_loc, 1, 0, proj.data); + // Bind current texture + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, self.current_texture); + glUniform1i(self.tex_loc, 0); + glBindVertexArray(self.vao); glBindBuffer(GL_ARRAY_BUFFER, self.vbo); @@ -171,39 +192,66 @@ UIRenderer :: struct { glBindVertexArray(0); self.vertex_count = 0; } + + render_text :: (self: *UIRenderer, node: RenderNode) { + font := g_font; + scale := node.font_size / font.font_size; + + self.bind_texture(font.texture_id); + + r := node.text_color.rf(); + g := node.text_color.gf(); + b := node.text_color.bf(); + a := node.text_color.af(); + + // stbtt_GetBakedQuad works at baked size; we scale output positions + xpos : f32 = 0.0; + ypos : f32 = 0.0; + q : AlignedQuad = ---; + i : s64 = 0; + while i < node.text.len { + ch : s32 = xx node.text[i]; + if ch >= FIRST_CHAR and ch < FIRST_CHAR + NUM_CHARS { + stbtt_GetBakedQuad(xx font.char_data, ATLAS_W, ATLAS_H, ch - FIRST_CHAR, @xpos, @ypos, xx @q, 1); + + // Scale and offset to frame position + // ypos=0 means baseline is at y=0; glyphs go above (negative yoff) + // Add ascent so top of text aligns with frame top + gx0 := node.frame.origin.x + q.x0 * scale; + gy0 := node.frame.origin.y + font.ascent * scale + q.y0 * scale; + gx1 := node.frame.origin.x + q.x1 * scale; + gy1 := node.frame.origin.y + font.ascent * scale + q.y1 * scale; + + if self.vertex_count + 6 > MAX_UI_VERTICES { + self.flush(); + } + + // corner_radius = -1.0 signals "text mode" to the fragment shader + self.write_vertex(gx0, gy0, q.s0, q.t0, r, g, b, a, 0.0 - 1.0, 0.0, 0.0, 0.0); + self.write_vertex(gx1, gy0, q.s1, q.t0, r, g, b, a, 0.0 - 1.0, 0.0, 0.0, 0.0); + self.write_vertex(gx0, gy1, q.s0, q.t1, r, g, b, a, 0.0 - 1.0, 0.0, 0.0, 0.0); + self.write_vertex(gx1, gy0, q.s1, q.t0, r, g, b, a, 0.0 - 1.0, 0.0, 0.0, 0.0); + self.write_vertex(gx1, gy1, q.s1, q.t1, r, g, b, a, 0.0 - 1.0, 0.0, 0.0, 0.0); + self.write_vertex(gx0, gy1, q.s0, q.t1, r, g, b, a, 0.0 - 1.0, 0.0, 0.0, 0.0); + } + i += 1; + } + + self.bind_texture(self.white_texture); + } } -// Additional GL functions needed for UI renderer -GL_SCISSOR_TEST :u32: 0x0C11; -GL_DYNAMIC_DRAW :u32: 0x88E8; -GL_TEXTURE_2D :u32: 0x0DE1; -GL_TEXTURE_MIN_FILTER :u32: 0x2801; -GL_TEXTURE_MAG_FILTER :u32: 0x2800; -GL_NEAREST :u32: 0x2600; -GL_RGBA :u32: 0x1908; -GL_UNSIGNED_BYTE :u32: 0x1401; -GL_SRC_ALPHA :u32: 0x0302; -GL_ONE_MINUS_SRC_ALPHA :u32: 0x0303; - -glScissor : (s32, s32, s32, s32) -> void = ---; -glBufferSubData : (u32, s64, s64, *void) -> void = ---; -glGenTextures : (s32, *u32) -> void = ---; -glBindTexture : (u32, u32) -> void = ---; -glTexImage2D : (u32, s32, s32, s32, s32, s32, u32, u32, *void) -> void = ---; -glTexParameteri : (u32, u32, s32) -> void = ---; -glBlendFunc : (u32, u32) -> void = ---; -glReadPixels : (s32, s32, s32, s32, u32, u32, *void) -> void = ---; - -// Load additional GL functions (call after load_gl) -load_gl_ui :: (get_proc: ([:0]u8) -> *void) { - glScissor = xx get_proc("glScissor"); - glBufferSubData = xx get_proc("glBufferSubData"); - glGenTextures = xx get_proc("glGenTextures"); - glBindTexture = xx get_proc("glBindTexture"); - glTexImage2D = xx get_proc("glTexImage2D"); - glTexParameteri = xx get_proc("glTexParameteri"); - glBlendFunc = xx get_proc("glBlendFunc"); - glReadPixels = xx get_proc("glReadPixels"); +// Upload font atlas bitmap as GL texture (called after GL init) +upload_font_texture :: (font: *FontAtlas) { + if font.bitmap == null { return; } + glGenTextures(1, @font.texture_id); + glBindTexture(GL_TEXTURE_2D, font.texture_id); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexImage2D(GL_TEXTURE_2D, 0, xx GL_R8, ATLAS_W, ATLAS_H, 0, GL_RED, GL_UNSIGNED_BYTE, font.bitmap); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, xx GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, xx GL_LINEAR); + context.allocator.dealloc(font.bitmap); + font.bitmap = null; } create_white_texture :: () -> u32 { @@ -219,7 +267,9 @@ create_white_texture :: () -> u32 { // --- UI Shaders --- -UI_VERT_SRC :: #string GLSL +// --- Desktop (Core Profile 3.3) shaders --- + +UI_VERT_SRC_CORE :: #string GLSL #version 330 core layout(location = 0) in vec2 aPos; layout(location = 1) in vec2 aUV; @@ -240,11 +290,13 @@ void main() { } GLSL; -UI_FRAG_SRC :: #string GLSL +UI_FRAG_SRC_CORE :: #string GLSL #version 330 core in vec2 vUV; in vec4 vColor; -in vec4 vParams; // corner_radius, border_width, rect_w, rect_h +in vec4 vParams; + +uniform sampler2D uTex; out vec4 FragColor; @@ -258,7 +310,11 @@ void main() { float border = vParams.y; vec2 rectSize = vParams.zw; - if (radius > 0.0 || border > 0.0) { + if (radius < 0.0) { + float textAlpha = texture(uTex, vUV).r; + FragColor = vec4(vColor.rgb, vColor.a * textAlpha); + } else if (radius > 0.0 || border > 0.0) { + vec4 texColor = texture(uTex, vUV); vec2 half_size = rectSize * 0.5; vec2 center = (vUV - vec2(0.5)) * rectSize; float dist = roundedBoxSDF(center, half_size, radius); @@ -271,9 +327,80 @@ void main() { alpha = alpha * max(border_alpha, 0.0); } - FragColor = vec4(vColor.rgb, vColor.a * alpha); + FragColor = vec4(texColor.rgb * vColor.rgb, texColor.a * vColor.a * alpha); } else { - FragColor = vColor; + vec4 texColor = texture(uTex, vUV); + FragColor = texColor * vColor; + } +} +GLSL; + +// --- WASM (ES 3.0 / WebGL2) shaders --- + +UI_VERT_SRC_ES :: #string GLSL +#version 300 es +precision mediump float; +layout(location = 0) in vec2 aPos; +layout(location = 1) in vec2 aUV; +layout(location = 2) in vec4 aColor; +layout(location = 3) in vec4 aParams; + +uniform mat4 uProj; + +out vec2 vUV; +out vec4 vColor; +out vec4 vParams; + +void main() { + gl_Position = uProj * vec4(aPos, 0.0, 1.0); + vUV = aUV; + vColor = aColor; + vParams = aParams; +} +GLSL; + +UI_FRAG_SRC_ES :: #string GLSL +#version 300 es +precision mediump float; +in vec2 vUV; +in vec4 vColor; +in vec4 vParams; + +uniform sampler2D uTex; + +out vec4 FragColor; + +float roundedBoxSDF(vec2 center, vec2 half_size, float radius) { + vec2 q = abs(center) - half_size + vec2(radius); + return length(max(q, vec2(0.0))) + min(max(q.x, q.y), 0.0) - radius; +} + +void main() { + float radius = vParams.x; + float border = vParams.y; + vec2 rectSize = vParams.zw; + + if (radius < 0.0) { + float textAlpha = texture(uTex, vUV).r; + FragColor = vec4(vColor.rgb, vColor.a * textAlpha); + } else if (radius > 0.0 || border > 0.0) { + vec4 texColor = texture(uTex, vUV); + vec2 half_size = rectSize * 0.5; + vec2 center = (vUV - vec2(0.5)) * rectSize; + float dist = roundedBoxSDF(center, half_size, radius); + float aa = fwidth(dist); + float alpha = 1.0 - smoothstep(-aa, aa, dist); + + if (border > 0.0) { + float inner = roundedBoxSDF(center, half_size - vec2(border), max(radius - border, 0.0)); + float border_alpha = smoothstep(-aa, aa, inner); + alpha = alpha * max(border_alpha, 0.0); + } + + FragColor = vec4(texColor.rgb * vColor.rgb, texColor.a * vColor.a * alpha); + } else { + vec4 texColor = texture(uTex, vUV); + FragColor = texColor * vColor; } } GLSL; diff --git a/ui/scroll_view.sx b/ui/scroll_view.sx new file mode 100644 index 0000000..9bda1f6 --- /dev/null +++ b/ui/scroll_view.sx @@ -0,0 +1,148 @@ +#import "modules/std.sx"; +#import "modules/math"; +#import "ui/types.sx"; +#import "ui/render.sx"; +#import "ui/events.sx"; +#import "ui/view.sx"; + +ScrollAxes :: enum { vertical; horizontal; both; } + +ScrollView :: struct { + child: ViewChild; + offset: Point; + content_size: Size; + viewport_size: Size; + axes: ScrollAxes; + dragging: bool; + drag_pending: bool; + drag_start: Point; + drag_offset: Point; + + SCROLL_SPEED :f32: 20.0; + DRAG_THRESHOLD :f32: 4.0; + + clamp_offset :: (self: *ScrollView) { + max_x := max(0.0, self.content_size.width - self.viewport_size.width); + max_y := max(0.0, self.content_size.height - self.viewport_size.height); + + if self.axes == .vertical or self.axes == .both { + self.offset.y = clamp(self.offset.y, 0.0, max_y); + } else { + self.offset.y = 0.0; + } + + if self.axes == .horizontal or self.axes == .both { + self.offset.x = clamp(self.offset.x, 0.0, max_x); + } else { + self.offset.x = 0.0; + } + } +} + +impl View for ScrollView { + size_that_fits :: (self: *ScrollView, proposal: ProposedSize) -> Size { + // ScrollView takes all proposed space + Size.{ + width = proposal.width ?? 0.0, + height = proposal.height ?? 0.0 + }; + } + + layout :: (self: *ScrollView, bounds: Frame) { + self.viewport_size = bounds.size; + + // Measure child with infinite space on scroll axes + child_proposal := ProposedSize.{ + width = if self.axes == .horizontal or self.axes == .both then null else bounds.size.width, + height = if self.axes == .vertical or self.axes == .both then null else bounds.size.height + }; + self.content_size = self.child.view.size_that_fits(child_proposal); + self.clamp_offset(); + + // Layout child offset by scroll position + self.child.computed_frame = Frame.make( + bounds.origin.x - self.offset.x, + bounds.origin.y - self.offset.y, + self.content_size.width, + self.content_size.height + ); + self.child.view.layout(self.child.computed_frame); + } + + render :: (self: *ScrollView, ctx: *RenderContext, frame: Frame) { + ctx.push_clip(frame); + self.child.view.render(ctx, self.child.computed_frame); + ctx.pop_clip(); + } + + handle_event :: (self: *ScrollView, event: *Event, frame: Frame) -> bool { + if pos := event_position(event) { + print(" ScrollView.handle_event: pos=({},{}) frame=({},{},{},{})\n", pos.x, pos.y, frame.origin.x, frame.origin.y, frame.size.width, frame.size.height); + if !frame.contains(pos) { print(" -> outside frame\n"); return false; } + } + + if event.* == { + case .mouse_wheel: (d) { + if self.axes == .vertical or self.axes == .both { + self.offset.y -= d.delta.y * ScrollView.SCROLL_SPEED; + } + if self.axes == .horizontal or self.axes == .both { + self.offset.x -= d.delta.x * ScrollView.SCROLL_SPEED; + } + self.clamp_offset(); + return true; + } + case .mouse_down: (d) { + // Always record drag start (like Zig preHandleEvent) + self.drag_pending = true; + self.drag_start = d.position; + self.drag_offset = self.offset; + // Forward to children — let buttons/tappables handle too + self.child.view.handle_event(event, self.child.computed_frame); + return true; + } + case .mouse_moved: (d) { + // Activate drag once movement exceeds threshold + if self.drag_pending and !self.dragging { + dx := d.position.x - self.drag_start.x; + dy := d.position.y - self.drag_start.y; + dist := sqrt(dx * dx + dy * dy); + if dist >= ScrollView.DRAG_THRESHOLD { + self.dragging = true; + self.drag_pending = false; + // Cancel child press state — position far outside so on_tap won't fire + cancel :Event = .mouse_up(MouseButtonData.{ + position = Point.{ x = 0.0 - 10000.0, y = 0.0 - 10000.0 }, + button = .none + }); + self.child.view.handle_event(@cancel, self.child.computed_frame); + } + } + if self.dragging { + if self.axes == .vertical or self.axes == .both { + self.offset.y = self.drag_offset.y - (d.position.y - self.drag_start.y); + } + if self.axes == .horizontal or self.axes == .both { + self.offset.x = self.drag_offset.x - (d.position.x - self.drag_start.x); + } + self.clamp_offset(); + return true; + } + // Forward mouse_moved to children (for hover effects) + return self.child.view.handle_event(event, self.child.computed_frame); + } + case .mouse_up: { + was_dragging := self.dragging; + self.dragging = false; + self.drag_pending = false; + if was_dragging { + return true; + } + // Forward to children (for tap completion) + return self.child.view.handle_event(event, self.child.computed_frame); + } + } + // Forward other events to child + self.child.view.handle_event(event, self.child.computed_frame); + } +} diff --git a/ui/stacks.sx b/ui/stacks.sx index 37a5622..8ac3037 100644 --- a/ui/stacks.sx +++ b/ui/stacks.sx @@ -12,7 +12,7 @@ VStack :: struct { alignment: HAlignment; add :: (self: *VStack, view: View) { - self.children.append(ViewChild.make(view)); + self.children.append(ViewChild.{ view = view }); } } @@ -54,7 +54,7 @@ HStack :: struct { alignment: VAlignment; add :: (self: *HStack, view: View) { - self.children.append(ViewChild.make(view)); + self.children.append(ViewChild.{ view = view }); } } @@ -94,7 +94,7 @@ ZStack :: struct { alignment: Alignment; add :: (self: *ZStack, view: View) { - self.children.append(ViewChild.make(view)); + self.children.append(ViewChild.{ view = view }); } } diff --git a/ui/state.sx b/ui/state.sx new file mode 100644 index 0000000..491558b --- /dev/null +++ b/ui/state.sx @@ -0,0 +1,59 @@ +#import "modules/std.sx"; + +// --- State(T) — a handle to persistent storage --- + +State :: struct ($T: Type) { + ptr: *T; + + get :: (self: State(T)) -> T { self.ptr.*; } + + set :: (self: State(T), val: T) { self.ptr.* = val; } +} + +// --- StateEntry — type-erased storage --- + +StateEntry :: struct { + id: s64; + data: [*]u8; + size: s64; + generation: s64; +} + +// --- StateStore — manages persistent state --- + +StateStore :: struct { + entries: List(StateEntry); + current_generation: s64; + + init :: (self: *StateStore) { + self.entries = List(StateEntry).{}; + self.current_generation = 0; + } + + get_or_create :: (self: *StateStore, id: s64, $T: Type, default: T) -> State(T) { + // Search for existing entry + i : s64 = 0; + while i < self.entries.len { + if self.entries.items[i].id == id { + self.entries.items[i].generation = self.current_generation; + return State(T).{ ptr = xx self.entries.items[i].data }; + } + i += 1; + } + + // Create new entry + data : [*]u8 = xx context.allocator.alloc(size_of(T)); + memcpy(data, @default, size_of(T)); + self.entries.append(StateEntry.{ + id = id, + data = data, + size = size_of(T), + generation = self.current_generation + }); + State(T).{ ptr = xx data }; + } + + next_frame :: (self: *StateStore) { + self.current_generation += 1; + } +} diff --git a/ui/types.sx b/ui/types.sx index a200ad3..805c8d1 100644 --- a/ui/types.sx +++ b/ui/types.sx @@ -108,6 +108,15 @@ Color :: struct { with_alpha :: (self: Color, a: u8) -> Color { Color.{ r = self.r, g = self.g, b = self.b, a = a }; } + + lerp :: (self: Color, b: Color, t: f32) -> Color { + Color.{ + r = xx (self.r + (b.r - self.r) * t), + g = xx (self.g + (b.g - self.g) * t), + b = xx (self.b + (b.b - self.b) * t), + a = xx (self.a + (b.a - self.a) * t) + }; + } } // Named color constants diff --git a/ui/view.sx b/ui/view.sx index ad666b7..91b23b8 100644 --- a/ui/view.sx +++ b/ui/view.sx @@ -19,12 +19,5 @@ View :: protocol { // A child view with its computed frame (set during layout) ViewChild :: struct { view: View; - computed_frame: Frame; - - make :: (view: View) -> ViewChild { - ViewChild.{ - view = view, - computed_frame = Frame.zero() - }; - } + computed_frame: Frame = .zero(); } diff --git a/vendors/file_utils/file_utils.c b/vendors/file_utils/file_utils.c new file mode 100644 index 0000000..ef97dc3 --- /dev/null +++ b/vendors/file_utils/file_utils.c @@ -0,0 +1,14 @@ +#include +#include + +unsigned char* read_file_bytes(const char* path, int* out_size) { + FILE* f = fopen(path, "rb"); + if (!f) return 0; + fseek(f, 0, SEEK_END); + *out_size = (int)ftell(f); + fseek(f, 0, SEEK_SET); + unsigned char* buf = (unsigned char*)malloc(*out_size); + fread(buf, 1, *out_size, f); + fclose(f); + return buf; +} diff --git a/vendors/file_utils/file_utils.h b/vendors/file_utils/file_utils.h new file mode 100644 index 0000000..a3fabac --- /dev/null +++ b/vendors/file_utils/file_utils.h @@ -0,0 +1,6 @@ +#ifndef FILE_UTILS_H +#define FILE_UTILS_H + +unsigned char* read_file_bytes(const char* path, int* out_size); + +#endif diff --git a/vendors/kb_text_shape/kb/LICENSE b/vendors/kb_text_shape/kb/LICENSE new file mode 100644 index 0000000..cad70fa --- /dev/null +++ b/vendors/kb_text_shape/kb/LICENSE @@ -0,0 +1,19 @@ +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. \ No newline at end of file diff --git a/vendors/kb_text_shape/kb/README.md b/vendors/kb_text_shape/kb/README.md new file mode 100644 index 0000000..36dfc03 --- /dev/null +++ b/vendors/kb_text_shape/kb/README.md @@ -0,0 +1,70 @@ +# kb + +[Single-header](https://github.com/nothings/stb/blob/master/docs/stb_howto.txt) permissively-licensed libraries for C/C++. + +## Libraries + +- [kb\_text\_shape.h](./kb_text_shape.h): Unicode text segmentation and OpenType shaping + +## kb_text_shape.h + +![Example of Arabic shaping with stb_truetype](./images/arabic.png) +![Example of Hindi shaping with stb_truetype](./images/hindi.png) +![Example of Khmer shaping with stb_truetype](./images/khmer.png) +![Example of Myanmar shaping with stb_truetype](./images/myanmar.png) +![Example of Gunjala Gondi shaping with stb_truetype](./images/gunjala_gondi.png) +![Example of toggling the smallcaps font feature](./images/smallcaps.png) + +[kb\_text\_shape.h](./kb_text_shape.h) provides: +- ICU-like text segmentation (i.e. breaking Unicode text by direction, line, script, word and grapheme). +- Harfbuzz-like text shaping for OpenType fonts, which means it is capable of handling complex script layout and ligatures, among other things. +- Font coverage checking: know if a font can display a given string. + +It does **not** handle rasterization. It does **not** handle paragraph layout. It does **not** handle selection and loading of system fonts. It will only help you know which glyphs to display where on a single, infinitely-long line, using the fonts you have provided! + +(See https://www.newroadoldway.com/text1.html for an explanation of the different steps of text processing.) + +For an in-depth usage example, check out [refpad](https://github.com/JimmyLefevre/refpad). + +```c +// Yours to provide: +void DrawGlyph(kbts_u16 GlyphId, kbts_s32 GlyphOffsetX, kbts_s32 GlyphOffsetY, kbts_s32 GlyphAdvanceX, kbts_s32 GlyphAdvanceY, + kbts_direction ParagraphDirection, kbts_direction RunDirection, kbts_script Script, kbts_font *Font); +void NextLine(void); +void *CreateRenderFont(const char *FontPath); + +void HandleText(kbts_shape_context *Context, const char *Text, kbts_language Language) +{ + kbts_ShapeBegin(Context, KBTS_DIRECTION_DONT_KNOW, Language); + kbts_ShapeUtf8(Context, Text, (int)strlen(Text), KBTS_USER_ID_GENERATION_MODE_CODEPOINT_INDEX); + kbts_ShapeEnd(Context); + + kbts_run Run; + while(kbts_ShapeRun(Context, &Run)) + { + if(Run.Flags & KBTS_BREAK_FLAG_LINE_HARD) + { + NextLine(); + } + + kbts_glyph *Glyph; + while(kbts_GlyphIteratorNext(&Run.Glyphs, &Glyph)) + { + DrawGlyph(Glyph->Id, Glyph->OffsetX, Glyph->OffsetY, Glyph->AdvanceX, Glyph->AdvanceY, + Run.ParagraphDirection, Run.Direction, Run.Script, Run.Font); + } + } +} + +void Example(void) +{ + kbts_shape_context *Context = kbts_CreateShapeContext(0, 0); + kbts_font *FontA = kbts_ShapePushFontFromFile(Context, "NotoSansMyanmar-Regular.ttf", 0); + kbts_font *FontB = kbts_ShapePushFontFromFile(Context, "NotoSansArabic-Regular.ttf", 0); + + FontA->UserData = CreateRenderFont("NotoSansMyanmar-Regular.ttf"); + FontB->UserData = CreateRenderFont("NotoSansArabic-Regular.ttf"); + + HandleText(Context, (const char *)u8"یکအမည်မရှိیک", KBTS_LANGUAGE_ARABIC); +} +``` diff --git a/vendors/kb_text_shape/kb/images/arabic.png b/vendors/kb_text_shape/kb/images/arabic.png new file mode 100644 index 0000000000000000000000000000000000000000..7d769e21db32041781a1189187ac249974b76c04 GIT binary patch literal 9350 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಄)_bktbISI)MlhwwP7$5F6*gJzJ0GL#g?`9;#_}! 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 TYqVae-T+xiC5cLLlP~`dYF|D6 literal 0 HcmV?d00001 diff --git a/vendors/kb_text_shape/kb/images/hindi.png b/vendors/kb_text_shape/kb/images/hindi.png new file mode 100644 index 0000000000000000000000000000000000000000..526f5720cb47240271130ad0fb8c1b2e0ae070cb GIT binary patch literal 4846 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 U2XbQZU;qFB07*qoM6N<$f_}gb_y7O^ literal 0 HcmV?d00001 diff --git a/vendors/kb_text_shape/kb/images/khmer.png b/vendors/kb_text_shape/kb/images/khmer.png new file mode 100644 index 0000000000000000000000000000000000000000..1deb25f61155bc5bbd13d9562789f830f36ea131 GIT binary patch literal 4647 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 dz`!6O_}AC002ovPDHLkV1hdU+vETM literal 0 HcmV?d00001 diff --git a/vendors/kb_text_shape/kb/images/myanmar.png b/vendors/kb_text_shape/kb/images/myanmar.png new file mode 100644 index 0000000000000000000000000000000000000000..24f330ef67d93fe27cfa7fc19baab894f6baff93 GIT binary patch literal 8670 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 literal 0 HcmV?d00001 diff --git a/vendors/kb_text_shape/kb/images/smallcaps.png b/vendors/kb_text_shape/kb/images/smallcaps.png new file mode 100644 index 0000000000000000000000000000000000000000..8a926073f89f9ff4a180818fd5ebc3135f1cff7f GIT binary patch literal 4576 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 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 (kbts_shape_scratchpad) + 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_scratchpad *Scratchpad, kbts_glyph_storage *Storage, + kbts_direction RunDirection, 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. + + 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_GetFontInfo2 + :GetFontInfo2 + void kbts_GetFontInfo2(kbts_font *Font, kbts_font_info2 *Info) + Writes a bunch of useful metadata about [Font] into [Info]. + + Before calling this function, you must fill out [Info].Size to be + sizeof([Info]). + + [Info] can be one of several types: + - kbts_font_info2 describes styling, name and licensing information. + 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_info2_1 also includes metrics and bounding box information. + - kbts_font_info2_2 also includes capital height. + + :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, or some information could not be found in the + font, then the respective members will be zeroed (except Size). + + :kbts_GetFontInfo + :GetFontInfo + void kbts_GetFontInfo(kbts_font *Font, kbts_font_info *Info) + Equivalent to calling kbts_GetFontInfo2 with an Info struct of type + kbts_font_info2. + + 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:SHAPE SCRATCHPAD + :kbts_SizeOfShapeScratchpad + :SizeOfShapeScratchpad + kbts_un kbts_SizeOfShapeScratchpad(kbts_shape_config *Config) + Returns how large a scratchpad for [Config] will be initially. + This is the size of the initial memory footprint, used to hold basic bookkeeping data. + A scratchpad can always dynamically allocate memory during shaping. + + :kbts_PlaceShapeScratchpad + :PlaceShapeScratchpad + kbts_shape_scratchpad *kbts_PlaceShapeScratchpad(kbts_shape_config *Config, + void *Memory, + kbts_allocator_function *Allocator, void *AllocatorData) + Initializes a scratchpad for [Config] at [Memory], and returns a pointer to it. + [Memory] should be kbts_SizeOfShapeScratchpad(Config) big. + [Allocator] will be used by the scratchpad during shaping. + + If [Memory] is null, then the [return value] is null. + + :kbts_PlaceShapeScratchpadFixedMemory + :PlaceShapeScratchpadFixedMemory + kbts_shape_scratchpad *kbts_PlaceShapeScratchpadFixedMemory(kbts_shape_config *Config, + void *Memory, int Size) + Same as kbts_PlaceShapeScratchpad, except the buffer [Memory] of size [Size] + is used for both initialization and dynamic allocation. + + If [Size] is not large enough, then the [return value] is null. + + :kbts_CreateShapeScratchpad + :CreateShapeScratchpad + kbts_shape_scratchpad *kbts_CreateShapeScratchpad(kbts_shape_config *Config, + kbts_allocator_function *Allocator, void *AllocatorData) + Same as kbts_PlaceShapeScratchpad, except [Allocator] is used both for + initialization and for dynamic allocation. + + If [Allocator] is null, then the default allocator is used. + + :kbts_DestroyShapeScratchpad + :DestroyShapeScratchpad + void kbts_DestroyShapeScratchpad(kbts_shape_scratchpad *Scratchpad) + Frees all memory associated with [Scratchpad]. + + If [Scratchpad] itself was allocated with kbts_CreateShapeScratchpad, then + it will also free itself. + + 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 a one-based index into the array of alternatives.) + + :kbts_SizeOfGlyphConfig + :SizeOfGlyphConfig + int kbts_SizeOfGlyphConfig(kbts_shape_config *ShapeConfig, 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. + Overrides with values of 0 or 1 are stored in a compact format, while other values + will be stored explicitly. + + :kbts_PlaceGlyphConfig + :PlaceGlyphConfig + kbts_glyph_config *kbts_PlaceGlyphConfig(kbts_shape_config *ShapeConfig, 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_shape_config *ShapeConfig, 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): + \n generates a hard line break at position 1 + A generates no hard line break + + With this flag (Unicode behavior): + \n generates a hard line break at position 1 + A 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.10 - Properly zero extended font_info2 types in GetFontInfo2. + Properly reset the glyph config cache in ShapeBegin. + 2.09 - Fix use-after-free when a shape_scratchpad was freed after its respective shape_config. + Extended the GetFontInfo API to include metrics and bounding box information. + New types: kbts_font_info2, kbts_font_info2_1. + New function: kbts_GetFontInfo2(). + 2.08 - Fix some UB. + 2.07 - Performance improvements. + API CHANGES: + Struct layout changes for internal use: kbts_glyph, kbts_glyph_parent. + + CONTEXT API + - kbts_shape_codepoint now holds bespoke feature overrides instead of a glyph config. + BEFORE: + 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; + AFTER: + typedef struct kbts_shape_codepoint + { + kbts_font *Font; // Only set when (BreakFlags & KBTS_BREAK_FLAG_GRAPHEME) != 0. + + kbts_feature_override *FeatureOverrides; + int FeatureOverrideCount; + + 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; + + DIRECT API + - Added a new (opaque pointer) type: kbts_shape_scratchpad. + This type contains all the runtime data needed for shaping according to a specific kbts_shape_config. + Unlike the kbts_shape_config, it is mutable, and so cannot be trivially shared across threads. + It can be reused across different shaping calls as long as they all use the same shape_config. + - Added functions to manage scratchpads: + kbts_un kbts_SizeOfShapeScratchpad(kbts_shape_config *Config) + kbts_shape_scratchpad *kbts_PlaceShapeScratchpad(kbts_shape_config *Config, void *Memory, kbts_allocator_function *Allocator, void *AllocatorData) + kbts_shape_scratchpad *kbts_PlaceShapeScratchpadFixedMemory(kbts_shape_config *Config, void *Memory, int Size) + kbts_shape_scratchpad *kbts_CreateShapeScratchpad(kbts_shape_config *Config, kbts_allocator_function *Allocator, void *AllocatorData) + void kbts_DestroyShapeScratchpad(kbts_shape_scratchpad *Scratchpad) + - kbts_ShapeDirect now takes a kbts_shape_scratchpad instead of a kbts_shape_config and an allocator. + BEFORE: + 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) + AFTER: + kbts_shape_error kbts_ShapeDirect(kbts_shape_scratchpad *Scratchpad, kbts_glyph_storage *Storage, + kbts_direction RunDirection, kbts_glyph_iterator *Output) + - Removed kbts_ShapeDirectFixedMemory. (Use kbts_PlaceShapeScratchpadFixedMemory instead.) + - Glyph configs now correspond to exactly one shape config. + BEFORE: + int kbts_SizeOfGlyphConfig(kbts_feature_override *Overrides, int OverrideCount) + kbts_glyph_config *kbts_PlaceGlyphConfig(kbts_feature_override *Overrides, int OverrideCount, void *Memory) + kbts_glyph_config *kbts_CreateGlyphConfig(kbts_feature_override *Overrides, int OverrideCount, kbts_allocator_function *Allocator, void *AllocatorData) + AFTER: + int kbts_SizeOfGlyphConfig(kbts_shape_config *ShapeConfig, kbts_feature_override *Overrides, int OverrideCount) + kbts_glyph_config *kbts_PlaceGlyphConfig(kbts_shape_config *ShapeConfig, kbts_feature_override *Overrides, int OverrideCount, void *Memory) + kbts_glyph_config *kbts_CreateGlyphConfig(kbts_shape_config *ShapeConfig, kbts_feature_override *Overrides, int OverrideCount, kbts_allocator_function *Allocator, void *AllocatorData) + 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 kbts_b32 +# define kbts_b32 int +# 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 +# define kbts_uptr kbts_u32 +# else +# define kbts_un kbts_u64 +# define kbts_sn kbts_s64 +# define kbts_uptr kbts_u64 +# 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) ((kbts_u32)(A) | ((kbts_u32)(B) << 8) | ((kbts_u32)(C) << 16) | ((kbts_u32)(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_REMOVED_SUBTABLE_INFOS_ALIGNED_TABLES, + + KBTS_BLOB_VERSION_CURRENT = KBTS_BLOB_VERSION_REMOVED_SUBTABLE_INFOS_ALIGNED_TABLES, +}; + +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 << 20), + KBTS_GLYPH_FLAG_FIRST_IN_MULTIPLE_SUBSTITUTION = (1 << 21), + KBTS_GLYPH_FLAG_NO_BREAK = (1 << 22), + KBTS_GLYPH_FLAG_CURSIVE = (1 << 23), + KBTS_GLYPH_FLAG_GENERATED_BY_GSUB = (1 << 24), + KBTS_GLYPH_FLAG_USED_IN_GPOS = (1 << 25), + + KBTS_GLYPH_FLAG_STCH_ENDPOINT = (1 << 26), + KBTS_GLYPH_FLAG_STCH_EXTENSION = (1 << 27), + + KBTS_GLYPH_FLAG_LIGATURE = (1 << 28), + KBTS_GLYPH_FLAG_MULTIPLE_SUBSTITUTION = (1 << 29), +}; + +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_shape_scratchpad kbts_shape_scratchpad; + +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_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_font_info2 +{ + kbts_u32 Size; + + 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_info2; + +typedef struct kbts_font_info2_1 +{ + kbts_font_info2 Base; + + kbts_u16 UnitsPerEm; + + kbts_s16 XMin; + kbts_s16 YMin; + kbts_s16 XMax; + kbts_s16 YMax; + + kbts_s16 Ascent; + kbts_s16 Descent; + kbts_s16 LineGap; +} kbts_font_info2_1; + +typedef struct kbts_font_info2_2 +{ + kbts_font_info2 Base; + + // _1 + kbts_u16 UnitsPerEm; + + kbts_s16 XMin; + kbts_s16 YMin; + kbts_s16 XMax; + kbts_s16 YMax; + + kbts_s16 Ascent; + kbts_s16 Descent; + kbts_s16 LineGap; + + // _2 + + // For now, this is just OS2.sCapHeight. + // If/when this is zero, we might consider trying to communicate a useful height instead of simply passing the zero along. + kbts_s16 CapitalHeight; +} kbts_font_info2_2; + +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__bucketed_glyph kbts__bucketed_glyph; +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; + + // @Memory: We definitely don't need to carry this around for the entire shaping process. + kbts_u64 Decomposition; + + kbts_glyph_classes Classes; + + kbts_glyph_flags Flags; + + kbts_u32 ParentInfo; + + kbts__bucketed_glyph *Bucketed; + kbts_u32 SortKey; + kbts_u32 SortKeyInterval; + kbts_u16 BucketedBucketIndex; + + // 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_feature_override *FeatureOverrides; + int FeatureOverrideCount; + + 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_u32 Codepoint; + kbts_u32 Codepoint1; +} 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_scratchpad *Scratchpad, kbts_glyph_storage *Storage, kbts_direction RunDirection, 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); +KBTS_EXPORT void kbts_GetFontInfo2(kbts_font *Font, kbts_font_info2 *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_shape_config *ShapeConfig, kbts_feature_override *Overrides, int OverrideCount); +KBTS_EXPORT kbts_glyph_config *kbts_PlaceGlyphConfig(kbts_shape_config *ShapeConfig, kbts_feature_override *Overrides, int OverrideCount, void *Memory); +KBTS_EXPORT kbts_glyph_config *kbts_CreateGlyphConfig(kbts_shape_config *ShapeConfig, kbts_feature_override *Overrides, int OverrideCount, kbts_allocator_function *Allocator, void *AllocatorData); +KBTS_EXPORT void kbts_DestroyGlyphConfig(kbts_glyph_config *Config); + +// A shape_scratchpad holds all transient runtime shaping data. +// While the shape_config is immutable and can be trivially shared among threads, a +// shape_scratchpad is mutable and needs to be per-thread. +KBTS_EXPORT kbts_un kbts_SizeOfShapeScratchpad(kbts_shape_config *Config); +KBTS_EXPORT kbts_shape_scratchpad *kbts_PlaceShapeScratchpad(kbts_shape_config *Config, void *Memory, kbts_allocator_function *Allocator, void *AllocatorData); +KBTS_EXPORT kbts_shape_scratchpad *kbts_PlaceShapeScratchpadFixedMemory(kbts_shape_config *Config, void *Memory, int Size); +KBTS_EXPORT kbts_shape_scratchpad *kbts_CreateShapeScratchpad(kbts_shape_config *Config, kbts_allocator_function *Allocator, void *AllocatorData); +KBTS_EXPORT void kbts_DestroyShapeScratchpad(kbts_shape_scratchpad *Scratchpad); + +// +// 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 + +#ifdef KB_TEXT_SHAPE_IMPLEMENTATION +#ifdef _MSC_VER +#define KBTS__UNUSED(X) (void)sizeof((X)) +#define KBTS__RESTRICT __restrict +#else +#define KBTS__UNUSED(X) (void)(X) +#define KBTS__RESTRICT __restrict__ +#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__BIT_WIDTH(Type) (sizeof(Type)*8) + +#define KBTS__DELETED_SORT_KEY 0xFFFFFFFF + +#define KBTS__BUCKETED_GLYPHS_PER_BLOCK 64 +#define KBTS_LOOKUP_STACK_SIZE 32 + +# ifndef KBTS_ASSERT +#ifndef KB_TEXT_SHAPE_NO_CRT +# include +# define KBTS_ASSERT(Cond) assert(Cond) +#else +#define KBTS_ASSERT(Cond) +#endif +# endif + +#ifndef KB_TEXT_SHAPE_NO_CRT +#include +#endif + +#ifndef KBTS_MEMSET +#include +#define KBTS_MEMSET memset +#endif + +#ifndef KBTS_MEMCPY +#include +#define KBTS_MEMCPY memcpy +#endif + +#ifndef KB_TEXT_SHAPE_NO_CRT +#ifndef KBTS_MALLOC +#include +#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 +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 +KBTS_INLINE kbts_u32 kbts__MsbPositionOrZero32(kbts_u32 X) +{ + unsigned long Result; + if(!_BitScanReverse(&Result, X)) + { + Result = 0; + } + return (kbts_u32)Result; +} +KBTS_INLINE kbts_u32 kbts__LsbPositionOrBitWidth32(kbts_u32 X) +{ + unsigned long Result; + if(!_BitScanForward(&Result, X)) + { + Result = 32; + } + 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; +} +KBTS_INLINE kbts_u32 kbts__LsbPositionOrBitWidth32(kbts_u32 X) +{ + kbts_u32 Result = 32; + if(X) + { + Result = __builtin_ctz(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_BEGIN_GSUB, + 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_BEGIN_GSUB, + 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_BEGIN_GSUB, + 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_BEGIN_GSUB, + 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_BEGIN_GSUB, + 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_BEGIN_GSUB, + 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_BEGIN_GSUB, + 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_BEGIN_GSUB, + 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_BEGIN_GSUB, + 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_BEGIN_GSUB, + 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(Parent->Codepoint1 == 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; + + kbts_b32 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]; + + kbts_u64 Decomposition = kbts__GetUnicodeDecomposition(Parent.Codepoint); + Parent.Codepoint1 = kbts__GetDecompositionCodepoint(Decomposition, 1); + + kbts_u16 RecompositionId = (kbts_u16)kbts_CodepointToGlyphId(Test->Font, (int)Parent.Codepoint); + + if(RecompositionId) + { + if(kbts__GetDecompositionSize(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__enabled_lookup +{ + kbts_u16 SequentialLookupIndex; + kbts_u16 Value; +} kbts__enabled_lookup; + +typedef struct kbts_glyph_config +{ + kbts_allocator_function *Allocator; + void *AllocatorData; + + kbts_u32 *EnabledLookupBits; + kbts_u32 *DisabledLookupBits; + + kbts__enabled_lookup *NonBinaryEnabledLookups; + kbts_u32 NonBinaryEnabledLookupCount; +} 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__bucketed_glyph +{ + kbts_glyph *Glyph; + kbts_u32 SortKey; + kbts_u16 FeatureValue; +} kbts__bucketed_glyph; + +typedef struct kbts__bucketed_glyph_block_header +{ + struct kbts__bucketed_glyph_block_header *Prev; + struct kbts__bucketed_glyph_block_header *Next; +} kbts__bucketed_glyph_block_header; + +typedef struct kbts__bucketed_glyph_block +{ + kbts__bucketed_glyph_block_header Header; + kbts_b32 StartOfAllocation; + kbts_u32 Count; + kbts__bucketed_glyph Glyphs[KBTS__BUCKETED_GLYPHS_PER_BLOCK]; +} kbts__bucketed_glyph_block; + +#define KBTS_MAX_SIMULTANEOUS_FEATURES 32 +typedef struct kbts_shape_scratchpad +{ + kbts_allocator_function *Allocator; + void *AllocatorData; + kbts_b32 SelfAllocated; + + void *ScratchMemory; + + kbts_shape_config *Config; + + kbts_u32 *GlyphLookupSubtableMatrix; + kbts_u32 *LookupSubtableIndexOffsets; + kbts_u32 GlyphIdCount; + kbts_u32 LookupSubtableCount; + kbts_u32 GposLookupIndexOffset; + kbts_u32 SequentialLookupCount; + + kbts__bucketed_glyph_block_header *LookupGlyphBuckets; + kbts__bucketed_glyph_block_header FreeBucketedBlockSentinel; + + kbts__feature_set LookupFeatures; + + kbts__glyph_list Cluster; + kbts_b32 RealCluster; + kbts_b32 ClusterAtStartOfWord; + + kbts_glyph *LookupOnePastLastGlyph; + kbts_u32 LookupOnePastLastGlyphIndex; + + kbts_u32 NextGlyphUid; + + kbts_u32 Ip; + kbts__op_kind OpKind; + + kbts_direction RunDirection; + + kbts_u32 SequentialLookupIndexIndex; + kbts_u32 FeatureStagesRead; + + kbts_shape_error Error; +} kbts_shape_scratchpad; + +#define KBTS_CONTEXT_MAX_FONT_COUNT 32 + +#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__existing_glyph_config +{ + kbts_feature_override *FeatureOverrides; + int FeatureOverrideCount; + kbts_glyph_config *GlyphConfig; +} kbts__existing_glyph_config; + +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_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_feature_override *CurrentFeatureOverrides; + kbts_u32 CurrentFeatureOverrideCount; + 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; + kbts_b32 DoneShapingRuns; + + kbts_u32 ExistingShapeConfigCount; + kbts__existing_shape_config ExistingShapeConfigs[32]; + + kbts_u32 ExistingGlyphConfigCount; + kbts__existing_glyph_config ExistingGlyphConfigs[32]; + + kbts_u32 ScratchFeatureOverrideCount; + kbts_feature_override ScratchFeatureOverrides[KBTS_MAX_SIMULTANEOUS_FEATURES]; + + kbts_break_state BreakState; + + 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__sequential_lookup +{ + kbts_u32 GlyphFilter; + kbts_u32 SkipFlags; + kbts_u16 LookupIndex; +} kbts__sequential_lookup; + +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; + + kbts_u32 GlyphCount; + kbts_u32 LookupCount; + kbts_u16 *FeatureStageFirstLookupIndices; // [OpList.FeatureStageCount + 1] + kbts__sequential_lookup *SequentialLookups; // [LookupCount] + kbts_u32 *IdSequentialLookupMatrix; + + // Indic + kbts_glyph Virama; + + kbts_glyph DottedCircle; + kbts_glyph Whitespace; + + // Thai + kbts_glyph Nikhahit; + kbts_glyph SaraAa; +} 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) +{ + // This is doing byte iteration to work with unaligned arrays. + char *At = (char *)Array; + KBTS__FOR(WordIndex, 0, Count) + { + char Byte0 = At[0]; + char Byte1 = At[1]; + char Byte2 = At[2]; + char Byte3 = At[3]; + + At[0] = Byte3; + At[1] = Byte2; + At[2] = Byte1; + At[3] = Byte0; + + At += sizeof(kbts_u32); + } +} + +KBTS_INLINE kbts_u32 kbts__ReadU32Unaligned(kbts_u32 *Data) +{ + kbts_u32 Result; + KBTS_MEMCPY(&Result, (void *)Data, sizeof(kbts_u32)); + return Result; +} +KBTS_INLINE kbts_u16 kbts__ReadU16Unaligned(kbts_u16 *Data) +{ + kbts_u16 Result; + KBTS_MEMCPY(&Result, (void *)Data, sizeof(kbts_u16)); + return Result; +} +KBTS_INLINE void kbts__WriteU32Unaligned(kbts_u32 *Dest, kbts_u32 Value) +{ + KBTS_MEMCPY((void *)Dest, &Value, sizeof(kbts_u32)); +} +KBTS_INLINE void kbts__WriteU16Unaligned(kbts_u16 *Dest, kbts_u16 Value) +{ + KBTS_MEMCPY((void *)Dest, &Value, sizeof(kbts_u16)); +} + +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]; // 32 + kbts_u32 UnicodeRange[4]; // 42 + kbts_u32 VendorId; // 58 + kbts_u16 Selection; // 62 + kbts_u16 FirstCharacterIndex; // 64 + kbts_u16 LastCharacterIndex; // 66 + + // Some version 0 fonts support this, others do not. + kbts_s16 TypoAscender; // 68 + kbts_s16 TypoDescender; // 70 + kbts_s16 TypoLineGap; // 72 + 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); + kbts_un CoverageOffset = kbts__ReadU32Unaligned(&CoverageOffsets[MarkFilteringSetIndex]); + Result.MarkFilteringSet = KBTS__POINTER_OFFSET(kbts__coverage, MarkGlyphSets, CoverageOffset); + } + } + } + + 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 = FlatIndex % 32; + + return Result; +} + +static kbts__matrix_index kbts__IdSequentialLookupMatrixIndex(kbts_un SequentialLookupIndex, kbts_un GlyphIndex, kbts_un SequentialLookupCount) +{ + kbts_un BitsPerRow = (SequentialLookupCount + 31) & ~31; + kbts_un FlatIndex = GlyphIndex * BitsPerRow + SequentialLookupIndex; + + kbts__matrix_index Result = KBTS__ZERO; + Result.WordIndex = FlatIndex / 32; + Result.BitIndex = FlatIndex % 32; + + return Result; +} + +static kbts__matrix_index kbts__GlyphLookupSubtableMatrixIndex(kbts_un SubtableIndex, kbts_un SubtableCount, kbts_un GlyphIndex, kbts_un GlyphCount) +{ + kbts_un FlatIndex = SubtableIndex * GlyphCount + GlyphIndex; + + kbts__matrix_index Result = KBTS__ZERO; + Result.WordIndex = FlatIndex / 32; + Result.BitIndex = FlatIndex % 32; + + return Result; +} + +static kbts_un kbts__FlatLookupIndex(kbts_shape_scratchpad *Scratchpad, kbts_shaping_table ShapingTable, kbts_un LookupIndex) +{ + kbts_un Result = (ShapingTable == KBTS_SHAPING_TABLE_GSUB) ? LookupIndex : (LookupIndex + Scratchpad->GposLookupIndexOffset); + return Result; +} + +static kbts_b32 kbts__GlyphIncludedInLookupSubtable(kbts_shape_scratchpad *Scratchpad, + kbts_shaping_table ShapingTable, kbts_un LookupIndex, kbts_un SubtableIndex, + kbts_glyph *AtGlyph) +{ + KBTS_INSTRUMENT_FUNCTION_BEGIN; + kbts_b32 Result = 1; + + if(Scratchpad->GlyphLookupSubtableMatrix) + { + kbts_u32 *GlyphLookupSubtableMatrix = Scratchpad->GlyphLookupSubtableMatrix; + kbts_u32 *LookupSubtableIndexOffsets = Scratchpad->LookupSubtableIndexOffsets; + kbts_un GlyphCount = Scratchpad->GlyphIdCount; + kbts_un SubtableCount = Scratchpad->LookupSubtableCount; + + kbts_un FlatLookupIndex = kbts__FlatLookupIndex(Scratchpad, ShapingTable, LookupIndex); + kbts_un FlatSubtableIndex = LookupSubtableIndexOffsets[FlatLookupIndex] + SubtableIndex; + + kbts_un Id = AtGlyph->Id; + + if(Id < GlyphCount) + { + kbts__matrix_index MatrixIndex = kbts__GlyphLookupSubtableMatrixIndex(FlatSubtableIndex, SubtableCount, Id, GlyphCount); + if(!(GlyphLookupSubtableMatrix[MatrixIndex.WordIndex] & (1u << MatrixIndex.BitIndex))) + { + Result = 0; + } + } + } + + KBTS_INSTRUMENT_FUNCTION_END; + return Result; +} + +# 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) + { + kbts_u16 CmapFormat = kbts__ReadU16Unaligned(CmapBase); + switch(CmapFormat) + { + 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 kbts_b32 kbts__IsValidFeatureIteration(kbts__iterate_features *It) +{ + kbts_b32 Result = It->Langsys != 0; + return Result; +} + +static kbts_b32 kbts__NextFeature(kbts__iterate_features *It) +{ + kbts_b32 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 = (1u << (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 kbts_b32 kbts__NextLookup(kbts__iterate_lookups *It) +{ + kbts_b32 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; +} + +static void kbts__UnbucketGlyph(kbts_shape_scratchpad *Scratchpad, kbts_glyph *Glyph) +{ + if(Glyph->Bucketed) + { + Glyph->Bucketed->SortKey = KBTS__DELETED_SORT_KEY; + + Glyph->Bucketed = 0; + } +} + +static kbts_un kbts__IdLookupListIndex(kbts_un GlyphId, kbts_un GlyphCount) +{ + kbts_un Result = KBTS__MIN(GlyphId, GlyphCount); + return Result; +} + +#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_First = (First); \ + kbts_glyph *DllistSort_OnePastLast = (OnePastLast); \ + kbts_glyph *DllistSort_OneBeforeFirst = DllistSort_First->Prev; \ + for(kbts_glyph *DllistSort_Forward = DllistSort_First; \ + DllistSort_Forward != DllistSort_OnePastLast; \ + ) \ + { \ + kbts_glyph *DllistSort_Next = DllistSort_Forward->Next; \ + kbts_un DllistSort_Member = DllistSort_Forward->Member; \ + for(kbts_glyph *DllistSort_Backward = DllistSort_Forward; \ + DllistSort_Backward->Prev != DllistSort_OneBeforeFirst; \ + ) \ + { \ + if(DllistSort_Backward->Prev->Member > DllistSort_Member) \ + { \ + KBTS__DLLIST_SWAP(DllistSort_Backward, DllistSort_Backward->Prev); \ + } \ + else \ + { \ + break; \ + } \ + } \ + DllistSort_Forward = 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 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; + +typedef struct kbts__pointer_bump_allocator +{ + kbts_uptr At; +} kbts__pointer_bump_allocator; + +static kbts__pointer_bump_allocator kbts__PointerBumpAllocator(void *Pointer) +{ + kbts__pointer_bump_allocator Result; + Result.At = (kbts_uptr)Pointer; + return Result; +} + +static void *kbts__PointerPush(kbts__pointer_bump_allocator *Alloc, kbts_un Size, kbts_un Align) +{ + kbts_uptr Aligned = (Alloc->At + (Align - 1)) & ~(Align - 1); + Alloc->At = Aligned + Size; + + void *Result = (void *)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)) + +KBTS_INLINE kbts_un kbts__GsubSequentialLookupCount(kbts_shape_config *Config) +{ + kbts_un Result = Config->FeatureStageFirstLookupIndices[Config->OpList.FeatureStageCount - 1]; + return Result; +} + +KBTS_INLINE kbts_un kbts__SequentialLookupCount(kbts_shape_config *Config) +{ + kbts_un Result = Config->FeatureStageFirstLookupIndices[Config->OpList.FeatureStageCount]; + return Result; +} + +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; +} + +KBTS_EXPORT kbts_un kbts_SizeOfShapeScratchpad(kbts_shape_config *Config) +{ + kbts_un DecompositionSize = sizeof(kbts_glyph) * KBTS__MAXIMUM_DECOMPOSITION_CODEPOINTS; + kbts_un GsubSize = sizeof(kbts__gsub_frame) * KBTS_LOOKUP_STACK_SIZE; + kbts_un ScratchSize = KBTS__MAX(DecompositionSize, GsubSize); + + kbts_un Result = sizeof(kbts_shape_scratchpad) + ScratchSize; + + if(Config) + { + kbts_un BucketHeadersSize = sizeof(kbts__bucketed_glyph_block_header) * kbts__SequentialLookupCount(Config); + + Result += BucketHeadersSize; + } + + return Result; +} + +KBTS_EXPORT kbts_shape_scratchpad *kbts_PlaceShapeScratchpad(kbts_shape_config *Config, void *Memory, kbts_allocator_function *Allocator, void *AllocatorData) +{ + kbts__pointer_bump_allocator Bump = kbts__PointerBumpAllocator(Memory); + kbts_shape_scratchpad *Result = kbts__PointerPushType(&Bump, kbts_shape_scratchpad); + KBTS_MEMSET(Result, 0, sizeof(*Result)); + + if(!Allocator) + { + Allocator = kbts__DefaultAllocator; + } + + Result->Allocator = Allocator; + Result->AllocatorData = AllocatorData; + Result->Config = Config; + + // @Duplication with SizeOfShapeScratchpad(). + kbts_un DecompositionSize = sizeof(kbts_glyph) * KBTS__MAXIMUM_DECOMPOSITION_CODEPOINTS; + kbts_un GsubSize = sizeof(kbts__gsub_frame) * KBTS_LOOKUP_STACK_SIZE; + kbts_un ScratchSize = KBTS__MAX(DecompositionSize, GsubSize); + + Result->ScratchMemory = kbts__PointerPush(&Bump, ScratchSize, 1); + + if(Config) + { + kbts_un SequentialLookupCount = kbts__SequentialLookupCount(Config); + Result->LookupGlyphBuckets = kbts__PointerPushArray(&Bump, kbts__bucketed_glyph_block_header, SequentialLookupCount); + + { + kbts_blob_header *Blob = Config->Font->Blob; + + Result->GlyphIdCount = Blob->GlyphCount; + Result->LookupSubtableCount = Blob->LookupSubtableCount; + Result->GposLookupIndexOffset = Blob->GposLookupIndexOffset; + + if(Blob->GlyphLookupSubtableMatrixOffsetFromStartOfFile) + { + Result->GlyphLookupSubtableMatrix = KBTS__POINTER_OFFSET(kbts_u32, Blob, Blob->GlyphLookupSubtableMatrixOffsetFromStartOfFile); + } + + if(Blob->LookupSubtableIndexOffsetsOffsetFromStartOfFile) + { + Result->LookupSubtableIndexOffsets = KBTS__POINTER_OFFSET(kbts_u32, Blob, Blob->LookupSubtableIndexOffsetsOffsetFromStartOfFile); + } + } + + KBTS__FOR(LookupIndex, 0, SequentialLookupCount) + { + kbts__bucketed_glyph_block_header *Sentinel = &Result->LookupGlyphBuckets[LookupIndex]; + + KBTS__DLLIST_SENTINEL_INIT(Sentinel); + } + + Result->SequentialLookupCount = (kbts_u32)SequentialLookupCount; + } + + KBTS__DLLIST_SENTINEL_INIT(&Result->FreeBucketedBlockSentinel); + + return Result; +} + +KBTS_EXPORT kbts_shape_scratchpad *kbts_PlaceShapeScratchpadFixedMemory(kbts_shape_config *Config, void *Memory, int Size) +{ + kbts_shape_scratchpad *Result = 0; + kbts_un ScratchpadSize = kbts_SizeOfShapeScratchpad(Config); + kbts_un InitialSize = sizeof(kbts_arena) + ScratchpadSize; + + if((Size >= 0) && + ((kbts_un)Size >= InitialSize)) + { + kbts_arena *Arena = (kbts_arena *)KBTS__POINTER_OFFSET(kbts_arena, Memory, ScratchpadSize); + kbts__InitializeFixedMemoryArena(Arena, KBTS__POINTER_AFTER(void, Arena), (kbts_un)Size - InitialSize); + + Result = kbts_PlaceShapeScratchpad(Config, Memory, kbts__ArenaAllocator, Arena); + } + + return Result; +} + +KBTS_EXPORT kbts_shape_scratchpad *kbts_CreateShapeScratchpad(kbts_shape_config *Config, kbts_allocator_function *Allocator, void *AllocatorData) +{ + kbts_un Size = kbts_SizeOfShapeScratchpad(Config); + kbts_shape_scratchpad *Result = kbts_PlaceShapeScratchpad(Config, kbts__AllocatorAllocate(Allocator, AllocatorData, Size), Allocator, AllocatorData); + Result->SelfAllocated = 1; + return Result; +} + +static kbts__bucketed_glyph_block *kbts__NewBucketedGlyphBlock(kbts_shape_scratchpad *Scratchpad) +{ + kbts__bucketed_glyph_block_header *New = Scratchpad->FreeBucketedBlockSentinel.Prev; + if(New == &Scratchpad->FreeBucketedBlockSentinel) + { + // Allocate new blocks. + kbts_un BlocksToAllocateCount = 4096 / sizeof(kbts__bucketed_glyph_block); + kbts__bucketed_glyph_block *NewBlocks = (kbts__bucketed_glyph_block *)kbts__AllocatorAllocate(Scratchpad->Allocator, Scratchpad->AllocatorData, sizeof(kbts__bucketed_glyph_block) * BlocksToAllocateCount); + + if(NewBlocks) + { + KBTS__FOR(NewBlockIndex, 0, BlocksToAllocateCount) + { + kbts__bucketed_glyph_block *NewBlock = &NewBlocks[NewBlockIndex]; + NewBlock->Count = 0; + + if(NewBlockIndex) + { + KBTS__DLLIST_INSERT_BEFORE(&NewBlock->Header, &Scratchpad->FreeBucketedBlockSentinel); + NewBlock->StartOfAllocation = 0; + } + else + { + NewBlock->StartOfAllocation = 1; + } + } + + kbts__bucketed_glyph_block *NewBlock = &NewBlocks[0]; + New = &NewBlock->Header; + } + else + { + Scratchpad->Error = KBTS_SHAPE_ERROR_OUT_OF_MEMORY; + + return 0; + } + } + else + { + KBTS__DLLIST_REMOVE(New); + } + + kbts__bucketed_glyph_block *Result = (kbts__bucketed_glyph_block *)New; + Result->Count = 0; + + return Result; +} + +static kbts_shape_scratchpad *kbts__CreateShapeScratchpad(kbts_shape_config *Config, kbts_allocator_function *Allocator, void *AllocatorData) +{ + kbts_un ScratchpadSize = kbts_SizeOfShapeScratchpad(Config); + kbts_shape_scratchpad *Result = kbts_PlaceShapeScratchpad(Config, kbts__AllocatorAllocate(Allocator, AllocatorData, ScratchpadSize), Allocator, AllocatorData); + Result->SelfAllocated = 1; + + return Result; +} + +static kbts__bucketed_glyph *kbts__InsertGlyphIntoBucket(kbts_shape_scratchpad *Scratchpad, kbts_un BucketIndex, kbts_glyph *Glyph, kbts_u16 FeatureValue) +{ + kbts__bucketed_glyph Bucketed = KBTS__ZERO; + Bucketed.Glyph = Glyph; + Bucketed.SortKey = Glyph->SortKey; + Bucketed.FeatureValue = FeatureValue; + + kbts__bucketed_glyph_block_header *Sentinel = &Scratchpad->LookupGlyphBuckets[BucketIndex]; + kbts__bucketed_glyph_block_header *Header = Sentinel->Prev; + kbts_b32 NeedNewBlock = (Header == Sentinel); + if(!NeedNewBlock) + { + kbts__bucketed_glyph_block *LastBlock = (kbts__bucketed_glyph_block *)Header; + NeedNewBlock = (LastBlock->Count == KBTS__BUCKETED_GLYPHS_PER_BLOCK); + } + + if(NeedNewBlock) + { + kbts__bucketed_glyph_block *NewBlock = kbts__NewBucketedGlyphBlock(Scratchpad); + if(NewBlock) + { + KBTS__DLLIST_INSERT_BEFORE(&NewBlock->Header, Sentinel); + Header = &NewBlock->Header; + } + } + + kbts__bucketed_glyph_block *Block = (kbts__bucketed_glyph_block *)Header; + kbts__bucketed_glyph *Result = &Block->Glyphs[Block->Count++]; + + *Result = Bucketed; + + Glyph->Bucketed = Result; + Glyph->BucketedBucketIndex = (kbts_u16)BucketIndex; + + return Result; +} + +static kbts_b32 kbts__BucketGlyph(kbts_shape_scratchpad *Scratchpad, kbts_glyph *Glyph, kbts_un MinimumSequentialLookupIndex, kbts_b32 ScanBackwards) +{ + kbts_b32 Result = 0; + kbts_shape_config *Config = Scratchpad->Config; + kbts_un SequentialLookupCount = kbts__SequentialLookupCount(Config); + + if(MinimumSequentialLookupIndex < SequentialLookupCount) + { + kbts__matrix_index LastIndex = kbts__IdSequentialLookupMatrixIndex(SequentialLookupCount - 1, Glyph->Id, SequentialLookupCount); + kbts_un OnePastLastWordIndex = LastIndex.WordIndex + 1; + + if(Glyph->Id < Config->GlyphCount) + { + kbts_glyph_config *GlyphConfig = Glyph->Config; + + if(!GlyphConfig) + { + kbts_u32 *IdSequentialLookupMatrix = Config->IdSequentialLookupMatrix; + kbts__matrix_index MatrixIndex = kbts__IdSequentialLookupMatrixIndex(MinimumSequentialLookupIndex, Glyph->Id, SequentialLookupCount); + kbts_u32 *At = &IdSequentialLookupMatrix[MatrixIndex.WordIndex]; + // Mask out lookups < MinimumSequentialLookupIndex. + kbts_u32 BeforeFirstMask = ((1u << MatrixIndex.BitIndex) - 1); + kbts_u32 Bits = *At++ & ~BeforeFirstMask; + kbts_un SequentialLookupIndexOffset = 0; + + kbts_un WordIndex = MatrixIndex.WordIndex + 1; + while((WordIndex < OnePastLastWordIndex) && + !Bits) + { + Bits = *At++; + + WordIndex += 1; + SequentialLookupIndexOffset += KBTS__BIT_WIDTH(kbts_u32); + } + + if(Bits) + { + SequentialLookupIndexOffset += (kbts_un)kbts__LsbPositionOrBitWidth32(Bits) - (kbts_un)MatrixIndex.BitIndex; + kbts_un SequentialLookupIndex = MinimumSequentialLookupIndex + SequentialLookupIndexOffset; + kbts__InsertGlyphIntoBucket(Scratchpad, SequentialLookupIndex, Glyph, 1); + Result = 1; + } + } + else + { + kbts_u32 *IdSequentialLookupMatrix = Config->IdSequentialLookupMatrix; + kbts__matrix_index MatrixIndex = kbts__IdSequentialLookupMatrixIndex(MinimumSequentialLookupIndex, Glyph->Id, SequentialLookupCount); + kbts__matrix_index RowIndex = kbts__IdSequentialLookupMatrixIndex(MinimumSequentialLookupIndex, 0, SequentialLookupCount); + + kbts_u32 *At = &IdSequentialLookupMatrix[MatrixIndex.WordIndex]; + kbts_u32 *AtEnabled = &GlyphConfig->EnabledLookupBits[RowIndex.WordIndex]; + kbts_u32 *AtDisabled = &GlyphConfig->DisabledLookupBits[RowIndex.WordIndex]; + + // Mask out lookups < MinimumSequentialLookupIndex. + kbts_u32 BeforeFirstMask = ((1u << MatrixIndex.BitIndex) - 1); + + kbts_u32 Bits = ((*At++ | *AtEnabled++) & ~(*AtDisabled++)) & ~BeforeFirstMask; + kbts_un SequentialLookupIndexOffset = 0; + + kbts_un WordIndex = MatrixIndex.WordIndex + 1; + while((WordIndex < OnePastLastWordIndex) && + !Bits) + { + Bits = ((*At++ | *AtEnabled++) & ~(*AtDisabled++)); + + WordIndex += 1; + SequentialLookupIndexOffset += KBTS__BIT_WIDTH(kbts_u32); + } + + if(Bits) + { + SequentialLookupIndexOffset += (kbts_un)kbts__LsbPositionOrBitWidth32(Bits) - (kbts_un)MatrixIndex.BitIndex; + kbts_un SequentialLookupIndex = MinimumSequentialLookupIndex + SequentialLookupIndexOffset; + kbts_u16 FeatureValue = 1; + + KBTS__FOR(NonBinaryEnabledLookupIndex, 0, GlyphConfig->NonBinaryEnabledLookupCount) + { + kbts__enabled_lookup *Enabled = &GlyphConfig->NonBinaryEnabledLookups[NonBinaryEnabledLookupIndex]; + + if(Enabled->SequentialLookupIndex == SequentialLookupIndex) + { + FeatureValue = (kbts_u16)Enabled->Value; + + break; + } + } + + kbts__InsertGlyphIntoBucket(Scratchpad, SequentialLookupIndex, Glyph, FeatureValue); + Result = 1; + } + } + } + else + { + // Out-of-bounds glyphs traverse every lookup, I guess. + kbts__InsertGlyphIntoBucket(Scratchpad, MinimumSequentialLookupIndex, Glyph, 1); + } + } + + return Result; +} + +KBTS_INLINE void kbts__GsubMutate(kbts_shape_scratchpad *Scratchpad, kbts_font *Font, kbts_glyph *Glyph, kbts_un CurrentSequentialLookupIndex, 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; + + kbts__UnbucketGlyph(Scratchpad, Glyph); + kbts__BucketGlyph(Scratchpad, Glyph, CurrentSequentialLookupIndex + 1, 0); +} + +static kbts_b32 kbts__BucketedGlyphIsValid(kbts__bucketed_glyph *Bucketed) +{ + kbts_b32 Result = (Bucketed->SortKey != KBTS__DELETED_SORT_KEY); + return Result; +} + +static void kbts__FreeBucketedGlyphBlock(kbts_shape_scratchpad *Scratchpad, kbts__bucketed_glyph_block *Block) +{ + KBTS__DLLIST_REMOVE(&Block->Header); + KBTS__DLLIST_INSERT_BEFORE(&Block->Header, &Scratchpad->FreeBucketedBlockSentinel); +} + +static void kbts__SortGlyphBucket(kbts_shape_scratchpad *Scratchpad, kbts_un SequentialLookupIndex) +{ + kbts__bucketed_glyph_block_header *Sentinel = &Scratchpad->LookupGlyphBuckets[SequentialLookupIndex]; + + // @Speed: Use merge sort? + kbts__bucketed_glyph_block *ForwardBlock = (kbts__bucketed_glyph_block *)Sentinel->Next; + + kbts_un DeletedCount = 0; + if(&ForwardBlock->Header != Sentinel) + { + DeletedCount += (ForwardBlock->Glyphs[0].SortKey == KBTS__DELETED_SORT_KEY); + } + + kbts_un ForwardIndex = 1; + if(ForwardIndex == ForwardBlock->Count) + { + ForwardBlock = (kbts__bucketed_glyph_block *)ForwardBlock->Header.Next; + ForwardIndex = 0; + } + + while(&ForwardBlock->Header != Sentinel) + { + kbts__bucketed_glyph Bucketed = ForwardBlock->Glyphs[ForwardIndex]; + kbts_u32 SortKey = Bucketed.SortKey; + + kbts__bucketed_glyph_block *BackwardBlock = ForwardBlock; + kbts_un BackwardIndex = ForwardIndex; + for(;;) + { + kbts__bucketed_glyph_block *NextBackwardBlock = BackwardBlock; + kbts_un NextBackwardIndex = BackwardIndex; + if(NextBackwardIndex) + { + NextBackwardIndex -= 1; + } + else + { + NextBackwardBlock = (kbts__bucketed_glyph_block *)BackwardBlock->Header.Prev; + + if(&NextBackwardBlock->Header == Sentinel) + { + break; + } + + NextBackwardIndex = NextBackwardBlock->Count - 1; + } + + kbts_u32 ScanSortKey = NextBackwardBlock->Glyphs[NextBackwardIndex].SortKey; + + if(ScanSortKey > SortKey) + { + kbts__bucketed_glyph *From = &NextBackwardBlock->Glyphs[NextBackwardIndex]; + kbts__bucketed_glyph *To = &BackwardBlock->Glyphs[BackwardIndex]; + + BackwardBlock->Glyphs[BackwardIndex] = NextBackwardBlock->Glyphs[NextBackwardIndex]; + + if(From->SortKey != KBTS__DELETED_SORT_KEY) + { + To->Glyph->Bucketed = To; + } + } + else + { + break; + } + + BackwardBlock = NextBackwardBlock; + BackwardIndex = NextBackwardIndex; + } + + kbts__bucketed_glyph *To = &BackwardBlock->Glyphs[BackwardIndex]; + *To = Bucketed; + if(SortKey != KBTS__DELETED_SORT_KEY) + { + To->Glyph->Bucketed = To; + } + + DeletedCount += (SortKey == KBTS__DELETED_SORT_KEY); + + ForwardIndex += 1; + if(ForwardIndex == ForwardBlock->Count) + { + ForwardBlock = (kbts__bucketed_glyph_block *)ForwardBlock->Header.Next; + ForwardIndex = 0; + } + } + + for(kbts__bucketed_glyph_block_header *Header = Sentinel->Prev; + Header != Sentinel; + ) + { + kbts__bucketed_glyph_block_header *Prev = Header->Prev; + kbts__bucketed_glyph_block *Block = (kbts__bucketed_glyph_block *)Header; + + if(DeletedCount >= Block->Count) + { + DeletedCount -= Block->Count; + + kbts__FreeBucketedGlyphBlock(Scratchpad, Block); + } + else + { + Block->Count -= DeletedCount; + + break; + } + + Header = Prev; + } +} + +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; + + // No matter what, clear bucketing information on new glyphs. + Result->Bucketed = 0; + } + + 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_shape_config *Config, 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__UnbucketGlyph(Scratchpad, Glyph); + + 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; +} + +typedef struct kbts__sequence_lookup_result +{ + kbts__sequence_lookup_record *Records; + 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. + kbts_b32 Matched; + + kbts_u16 RecordCount; + kbts_u16 InputSequenceCountIncludingSkippedGlyphs; +} kbts__sequence_lookup_result; + +typedef struct kbts__sequence_match +{ + kbts_glyph *OnePastMatchGlyph; + + kbts_u16 MatchCount; + kbts_u16 MatchOrSkipCount; +} 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 = (kbts_u16)CoverageIndex; + Result.MatchOrSkipCount = (kbts_u16)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 = (kbts_u16)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 kbts_b32 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 kbts_b32 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; + enum{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); + + kbts_b32 Result = 0; + + kbts_un OnePastLastGlyphIndex = StartIndex + 1; + kbts_glyph *OnePastLastGlyph = CurrentGlyph->Next; + + if(kbts__GlyphIncludedInLookupSubtable(Scratchpad, KBTS_SHAPING_TABLE_GPOS, LookupIndex, SubtableIndex, CurrentGlyph)) + { + // 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_u16 *Unpacked1Base; + kbts_u16 *Unpacked2Base; + kbts_u16 ValueFormat1; + kbts_u16 ValueFormat2 = 0; + kbts_un Size1; + kbts_un Size2; + + { + kbts__pair_adjustment_1 *Adjust = (kbts__pair_adjustment_1 *)Base; + ValueFormat1 = Adjust->ValueFormat1; + ValueFormat2 = Adjust->ValueFormat2; + + Size1 = kbts__PopCount32(ValueFormat1); + Size2 = kbts__PopCount32(ValueFormat2); + } + + if(Base[0] == 1) + { + kbts__pair_adjustment_1 *Adjust = (kbts__pair_adjustment_1 *)Base; + + 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_un PairCount = Set->Count; + + #define KBTS__PAIR_SEARCH(PairSize) \ + kbts_un PairSizeTimesPairIndex = 0; \ + while(PairCount > 1) \ + { \ + kbts_un HalfCount = PairCount / 2; \ + PairSizeTimesPairIndex = (PairRecords[PairSizeTimesPairIndex + HalfCount*PairSize - PairSize].SecondGlyph < NextGlyphId) ? (PairSizeTimesPairIndex + HalfCount*PairSize) : PairSizeTimesPairIndex; \ + PairCount -= HalfCount; \ + } \ + kbts__pair_value_record *PairRecord = PairRecords + PairSizeTimesPairIndex; \ + if(PairRecord->SecondGlyph == NextGlyphId) \ + { \ + kbts_u16 *Records = KBTS__POINTER_AFTER(kbts_u16, PairRecord); \ + Unpacked1Base = Records; \ + Unpacked2Base = Records + Size1; \ + goto ApplyPairPositioning; \ + } + + if(PairRecordSize == 2) + { + KBTS__PAIR_SEARCH(2); + } + else if(PairRecordSize == 3) + { + KBTS__PAIR_SEARCH(3); + } + else + { + kbts__pair_value_record *PairRecord = PairRecords; + + while(PairCount > 1) + { + kbts_un HalfCount = PairCount / 2; + + kbts__pair_value_record *OnePastProbe = PairRecord + HalfCount * PairRecordSize; + kbts__pair_value_record *Probe = OnePastProbe - PairRecordSize; + + if(Probe->SecondGlyph < NextGlyphId) + { + PairRecord = OnePastProbe; + } + + PairCount -= HalfCount; + } + + if(PairRecord->SecondGlyph == NextGlyphId) + { + kbts_u16 *Records = KBTS__POINTER_AFTER(kbts_u16, PairRecord); + + Unpacked1Base = Records; + Unpacked2Base = Records + Size1; + goto ApplyPairPositioning; + } + } + + #undef KBTS__PAIR_SEARCH + } + 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 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; + + Unpacked1Base = PairRecord; + Unpacked2Base = PairRecord + Size1; + + goto ApplyPairPositioning; + } + } + + if(0) + { + ApplyPairPositioning:; + kbts__unpacked_value_record Unpacked1 = kbts__UnpackValueRecord(Base, ValueFormat1, Unpacked1Base); + kbts__ApplyValueRecord(CurrentGlyph, &Unpacked1); + + CurrentGlyph->Flags |= KBTS_GLYPH_FLAG_USED_IN_GPOS; + NextGlyph->Flags |= KBTS_GLYPH_FLAG_USED_IN_GPOS; + + OnePastLastGlyph = CurrentGlyph->Next; + + if(ValueFormat2) + { + kbts__unpacked_value_record Unpacked2 = kbts__UnpackValueRecord(Base, ValueFormat2, Unpacked2Base); + kbts__ApplyValueRecord(NextGlyph, &Unpacked2); + OnePastLastGlyph = NextGlyph->Next; + } + + Result = 1; + } + } + } + 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), + KBTS__SUBSTITUTION_RESULT_FLAG_MATCHED_SEQUENCE = (1 << 2), +}; + +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_un kbts__CurrentBakedFeatureStageIndex(kbts_shape_scratchpad *Scratchpad) +{ + kbts_un Result = Scratchpad->FeatureStagesRead - 1; + return Result; +} + +KBTS_INLINE kbts_u16 kbts__NextGlyphUid(kbts_shape_scratchpad *Scratchpad) +{ + kbts_u16 Result = (kbts_u16)++Scratchpad->NextGlyphUid; + 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_un SequentialLookupIndex, kbts_u16 FeatureValue, + 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; + + kbts_glyph *CurrentGlyph = Frame->InputGlyph; + + 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); + } + + if(kbts__GlyphIncludedInLookupSubtable(Scratchpad, KBTS_SHAPING_TABLE_GSUB, Frame->LookupIndex, Frame->SubtableIndex, CurrentGlyph)) + { + 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(Scratchpad, Font, CurrentGlyph, SequentialLookupIndex, 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_un RunningSortKey = CurrentGlyph->SortKey; + kbts_un SortKeyInterval = CurrentGlyph->SortKeyInterval / Sequence->GlyphCount; + 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__NextGlyphUid(Scratchpad); + } + else + { + NewGlyphFlags |= KBTS_GLYPH_FLAG_FIRST_IN_MULTIPLE_SUBSTITUTION; + } + + NewGlyph->SortKey = (kbts_u32)RunningSortKey; + NewGlyph->SortKeyInterval = (kbts_u32)SortKeyInterval; + + kbts__GsubMutate(Scratchpad, Font, NewGlyph, SequentialLookupIndex, SubstGlyphIds[SubstGlyphIndex], GeneratedGlyphFlags | NewGlyphFlags); + + LastInsert = NewGlyph; + RunningSortKey += SortKeyInterval; + } + + OnePastLastGlyph = LastInsert->Next; + } + else + { + kbts__FreeGlyph(Scratchpad, Config, 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 = FeatureValue - 1; + if(AlternateIndex >= Set->GlyphCount) + { + AlternateIndex = 0; + } + + kbts_u16 NewId = AltGlyphIds[AlternateIndex]; + kbts__GsubMutate(Scratchpad, Font, CurrentGlyph, SequentialLookupIndex, 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 = kbts__NextGlyphUid(Scratchpad); + + { // 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, Config, 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(Scratchpad, Font, CurrentGlyph, SequentialLookupIndex, 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(Scratchpad, Font, CurrentGlyph, SequentialLookupIndex, 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, 0, 0, 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 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__FreeGlyphBucket(kbts_shape_scratchpad *Scratchpad, kbts_un SequentialLookupIndex) +{ + kbts__bucketed_glyph_block_header *Sentinel = &Scratchpad->LookupGlyphBuckets[SequentialLookupIndex]; + + kbts__bucketed_glyph_block_header *First = Sentinel->Next; + kbts__bucketed_glyph_block_header *Last = Sentinel->Prev; + if(First != Sentinel) + { + First->Prev = Scratchpad->FreeBucketedBlockSentinel.Prev; + Last->Next = &Scratchpad->FreeBucketedBlockSentinel; + + First->Prev->Next = First; + Last->Next->Prev = Last; + + KBTS__DLLIST_SENTINEL_INIT(Sentinel); + } +} + +static void kbts__ExecuteOp(kbts_shape_scratchpad *Scratchpad, kbts_glyph_storage *Storage) +{ + KBTS_INSTRUMENT_FUNCTION_BEGIN; + kbts_shape_config *Config = Scratchpad->Config; + + 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_glyph *DecompositionGlyphs = (kbts_glyph *)Scratchpad->ScratchMemory; + 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, Config, 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_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_glyph *LastBase = 0; + kbts_un LastBaseParentCount = 0; + kbts_un PreSlashDecimalDigitCount = 0; + kbts_glyph *PreSlashGlyph = 0; + kbts_glyph *DigitGlyph = 0; + kbts_un DecimalDigitCount = 0; + kbts_b32 InFraction = 0; + kbts_u32 LastBaseParentsLoaded = 0; + kbts_glyph_parent LastBaseParents[KBTS_MAXIMUM_RECOMPOSITION_PARENTS]; + kbts_u16 LastBaseParentIds[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; + } + + kbts_b32 ShouldFlip = (Scratchpad->RunDirection == KBTS_DIRECTION_RTL); + + KBTS__FOR_GLYPH(Storage, Glyph) + { + Glyph->Uid = kbts__NextGlyphUid(Scratchpad); + + // 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, Glyph->Config, 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]; + + kbts_u64 Decomposition = kbts__GetUnicodeDecomposition(Parent.Codepoint); + Parent.Codepoint1 = kbts__GetDecompositionCodepoint(Decomposition, 1); + + kbts_un DecompositionSize = kbts__GetDecompositionSize(Decomposition); + if(DecompositionSize == 1) + { + SingleRecompositionCodepoints[SingleRecompositionCodepointCount++] = Parent.Codepoint; + } + else + { + LastBaseParents[DoubleDecompositionCount++] = Parent; + } + } + + LastBaseParentCount = DoubleDecompositionCount; + LastBaseParentsLoaded = 0; + } + else + { + LastBaseParentCount = 0; + } + + DoubleRecompositionCount = 0; + } + + kbts_b32 Recomposed = 0; + + if(!Recomposed) + { + KBTS_INSTRUMENT_BLOCK_BEGIN(ParentNSquaredStupidity); + KBTS__FOR(ParentIndex, 0, DoubleRecompositionCount) + { + kbts_glyph_parent *Parent = &LastBaseParents[ParentIndex]; + kbts_u32 Codepoint1 = Parent->Codepoint1; + + if(Glyph->Codepoint == Codepoint1) + { + kbts_u16 ParentId = LastBaseParentIds[ParentIndex]; + + if(!(LastBaseParentsLoaded & (1u << ParentIndex))) + { + ParentId = (kbts_u16)kbts_CodepointToGlyphId(Font, (int)Parent->Codepoint); + LastBaseParentIds[ParentIndex] = ParentId; + } + + if(ParentId) + { + // Both match. Reclaim space. + kbts_glyph ParentGlyph = kbts_CodepointToGlyph(Font, (int)Parent->Codepoint, 0, 0); + ParentGlyph.Uid = LastBase->Uid; + ParentGlyph.UserIdOrCodepointIndex = LastBase->UserIdOrCodepointIndex; + ParentGlyph.Config = LastBase->Config; + + 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]; + LastBaseParentIds[ParentIndex] = LastBaseParentIds[LastBaseParentCount - 1]; + LastBaseParentsLoaded &= ~(1u << ParentIndex); + LastBaseParentsLoaded |= (LastBaseParentsLoaded & (1u << (LastBaseParentCount - 1))) >> (LastBaseParentCount - 1 - ParentIndex); + + LastBaseParentCount -= 1; + DoubleRecompositionCount -= 1; + ParentIndex -= 1; + } + } + } + KBTS_INSTRUMENT_BLOCK_END(ParentNSquaredStupidity); + } + + if(!Recomposed) + { + KBTS__FOR(SingleRecompositionIndex, 0, SingleRecompositionCodepointCount) + { + kbts_u16 ParentGlyphId = (kbts_u16)kbts_CodepointToGlyphId(Font, (int)SingleRecompositionCodepoints[SingleRecompositionIndex]); + + if(ParentGlyphId) + { + kbts_glyph ParentGlyph = kbts_CodepointToGlyph(Font, (int)SingleRecompositionCodepoints[SingleRecompositionIndex], 0, 0); + 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. + } + } + } + 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) + { + enum {KBTS_REMAPPED_CCC_33 = 27}; + + 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; + + 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_glyph_config *GlyphConfig = Glyph->Config; + kbts__SetGlyphPreserveLinksAndUserId(Glyph, &Config->SaraAa); + Glyph->Config = GlyphConfig; + } 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_BEGIN_GSUB: + { + enum{SortKeyInterval = 0x10000}; + kbts_un RunningSortKey = SortKeyInterval; + + KBTS__FOR_GLYPH(Storage, Glyph) + { + Glyph->SortKey = (kbts_u32)RunningSortKey; + Glyph->SortKeyInterval = SortKeyInterval; + + kbts__BucketGlyph(Scratchpad, Glyph, 0, 0); + + RunningSortKey += SortKeyInterval; + } + } break; + + case KBTS__OP_KIND_GSUB_FEATURES: + { + KBTS_INSTRUMENT_BLOCK_BEGIN(GSUB_FEATURES); + + // @Duplication + kbts__gsub_gpos *FontGsub = kbts__BlobTableDataType(Font->Blob, KBTS_BLOB_TABLE_ID_GSUB, kbts__gsub_gpos); + kbts_lookup_list *LookupList = kbts__GetLookupList(FontGsub); + + kbts__gsub_frame *Frames = (kbts__gsub_frame *)Scratchpad->ScratchMemory; + + kbts_u32 FilterMask = Config->Shaper == KBTS_SHAPER_USE ? KBTS__USE_GLYPH_FEATURE_MASK : KBTS__GLYPH_FEATURE_MASK; + + kbts_un FeatureStageIndex = kbts__CurrentBakedFeatureStageIndex(Scratchpad); + kbts_un FirstSequentialLookupIndex = Config->FeatureStageFirstLookupIndices[FeatureStageIndex]; + kbts_un OnePastLastSequentialLookupIndex = Config->FeatureStageFirstLookupIndices[FeatureStageIndex + 1]; + KBTS__FOR(SequentialLookupIndex, FirstSequentialLookupIndex, OnePastLastSequentialLookupIndex) + { + kbts__sequential_lookup *SequentialLookup = &Config->SequentialLookups[SequentialLookupIndex]; + kbts_un LookupIndex = SequentialLookup->LookupIndex; + kbts_u32 SkipFlags = SequentialLookup->SkipFlags; + kbts_u32 GlyphFilter = SequentialLookup->GlyphFilter; + + kbts__bucketed_glyph_block_header *Sentinel = &Scratchpad->LookupGlyphBuckets[SequentialLookupIndex]; + + if(Sentinel->Next != Sentinel) + { + kbts__lookup *PackedLookup = kbts__GetLookup(LookupList, LookupIndex); + kbts_b32 LookupTypeIs8 = (PackedLookup->Type == 8); + + KBTS_INSTRUMENT_BLOCK_BEGIN(GsubSortBucket); + + if(PackedLookup->Type >= 4) + { + kbts__SortGlyphBucket(Scratchpad, SequentialLookupIndex); + } + + KBTS_INSTRUMENT_BLOCK_END(GsubSortBucket); + + for(kbts__bucketed_glyph_block_header *BlockHeader = (LookupTypeIs8) ? Sentinel->Prev : Sentinel->Next; + BlockHeader != Sentinel; + BlockHeader = (LookupTypeIs8) ? BlockHeader->Prev : BlockHeader->Next) + { + kbts__bucketed_glyph_block *Block = (kbts__bucketed_glyph_block *)BlockHeader; + kbts_un BlockGlyphCount = Block->Count; + + KBTS__FOR(GlyphIndex_, 0, BlockGlyphCount) + { + kbts_un GlyphIndex = (LookupTypeIs8) ? (BlockGlyphCount - 1 - GlyphIndex_) : GlyphIndex_; + kbts__bucketed_glyph *Bucketed = &Block->Glyphs[GlyphIndex]; + + if(kbts__BucketedGlyphIsValid(Bucketed)) + { + kbts_glyph *Glyph = Bucketed->Glyph; + kbts_u16 FeatureValue = Bucketed->FeatureValue; + kbts_u32 GlyphFlags = Glyph->Flags; + kbts_glyph *Prev = Glyph->Prev; + + kbts__BeginLookupApplication(Scratchpad, Glyph); + kbts_u32 EffectiveGlyphFilter = GlyphFilter & FilterMask; + + if((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, SequentialLookupIndex, FeatureValue, Frames, &FrameCount, 0, SkipFlags, GeneratedGlyphFlags); + } + } + + kbts_glyph *OnePastLast = kbts__EndLookupApplication(Scratchpad); + + for(kbts_glyph *MatchedGlyph = Prev->Next; + MatchedGlyph != OnePastLast; + MatchedGlyph = MatchedGlyph->Next) + { + // Queue for the next bucket. + if(MatchedGlyph->Bucketed && + (MatchedGlyph->BucketedBucketIndex == SequentialLookupIndex)) + { + // We are scheduled for the current bucket. Cancel that, and move on to the next. + kbts__UnbucketGlyph(Scratchpad, MatchedGlyph); + kbts__BucketGlyph(Scratchpad, MatchedGlyph, SequentialLookupIndex + 1, 0); + } + } + } + } + } + } + + kbts__FreeGlyphBucket(Scratchpad, SequentialLookupIndex); + } + + Scratchpad->SequentialLookupIndexIndex = (kbts_u32)OnePastLastSequentialLookupIndex; + + 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. + kbts_b32 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); + + 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_lookup_list *LookupList = kbts__GetLookupList(Gpos); + kbts_un FeatureStageIndex = kbts__CurrentBakedFeatureStageIndex(Scratchpad); + + kbts_un FirstSequentialLookupIndex = Config->FeatureStageFirstLookupIndices[FeatureStageIndex]; + kbts_un OnePastLastSequentialLookupIndex = Config->FeatureStageFirstLookupIndices[FeatureStageIndex + 1]; + KBTS__FOR(SequentialLookupIndex, FirstSequentialLookupIndex, OnePastLastSequentialLookupIndex) + { + kbts__sequential_lookup *SequentialLookup = &Config->SequentialLookups[SequentialLookupIndex]; + kbts_un LookupIndex = SequentialLookup->LookupIndex; + kbts_u32 SkipFlags = SequentialLookup->SkipFlags; + + kbts__bucketed_glyph_block_header *Sentinel = &Scratchpad->LookupGlyphBuckets[SequentialLookupIndex]; + + if(Sentinel->Next != Sentinel) + { + kbts__lookup *PackedLookup = kbts__GetLookup(LookupList, LookupIndex); + kbts__unpacked_lookup Lookup = kbts__UnpackLookup(Gdef, PackedLookup); + kbts_un SubtableCount = PackedLookup->SubtableCount; + + KBTS_INSTRUMENT_BLOCK_BEGIN(GposSortBucket); + + if(PackedLookup->Type >= 2) + { + kbts__SortGlyphBucket(Scratchpad, SequentialLookupIndex); + } + + KBTS_INSTRUMENT_BLOCK_END(GposSortBucket); + + for(kbts__bucketed_glyph_block_header *BlockHeader = Sentinel->Next; + BlockHeader != Sentinel; + BlockHeader = BlockHeader->Next) + { + kbts__bucketed_glyph_block *Block = (kbts__bucketed_glyph_block *)BlockHeader; + kbts_un BlockGlyphCount = Block->Count; + + KBTS__FOR(GlyphIndex, 0, BlockGlyphCount) + { + kbts__bucketed_glyph *Bucketed = &Block->Glyphs[GlyphIndex]; + + if(kbts__BucketedGlyphIsValid(Bucketed)) + { + kbts_glyph *Glyph = Bucketed->Glyph; + kbts__BeginLookupApplication(Scratchpad, Glyph); + + kbts_u16 *SubtableOffsets = KBTS__POINTER_AFTER(kbts_u16, PackedLookup); + + KBTS__FOR(SubtableIndex, 0, SubtableCount) + { + kbts_u16 *Subtable = KBTS__POINTER_OFFSET(kbts_u16, PackedLookup, SubtableOffsets[SubtableIndex]); + + if(kbts__DoSingleAdjustment(Scratchpad, Config, Storage, + LookupList, LookupIndex, SubtableIndex, &Lookup, Subtable, + Glyph, 0, SkipFlags)) + { + break; + } + } + + kbts_glyph *OnePastLast = kbts__EndLookupApplication(Scratchpad); + + for(kbts_glyph *MatchedGlyph = Glyph; + MatchedGlyph != OnePastLast; + MatchedGlyph = MatchedGlyph->Next) + { + // Queue for the next bucket. + + if(MatchedGlyph->Bucketed && + (MatchedGlyph->BucketedBucketIndex == SequentialLookupIndex)) + { + // We are scheduled for the current bucket. Cancel that, and move on to the next. + kbts__UnbucketGlyph(Scratchpad, MatchedGlyph); + kbts__BucketGlyph(Scratchpad, MatchedGlyph, SequentialLookupIndex + 1, 1); + } + } + } + } + } + } + + kbts__FreeGlyphBucket(Scratchpad, SequentialLookupIndex); + } + + 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_glyph_config *GlyphConfig = Glyph->Config; + kbts__SetGlyphPreserveLinksAndUserId(Glyph, &WhitespaceGlyph); + Glyph->Config = GlyphConfig; + } + } + else + { + if(ClearMarkAdvances && (Glyph->Classes.Class == KBTS__GLYPH_CLASS_MARK)) + { + Glyph->AdvanceX = Glyph->AdvanceY = 0; + } + Keep = 1; + } + + if(!Keep) + { + kbts__FreeGlyph(Scratchpad, Config, 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, Scratchpad->SequentialLookupIndexIndex, 0, 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_glyph_storage *Storage, + kbts_glyph *Glyph) +{ + kbts_shape_config *Config = Scratchpad->Config; + kbts_font *Font = Config->Font; + kbts_glyph *Result = Glyph->Next; + + 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__gsub_frame *)Scratchpad->ScratchMemory; + 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; + } + + return Result; +} + +static void kbts__EndCluster(kbts_shape_scratchpad *Scratchpad, kbts_glyph_storage *Storage) +{ + kbts_shape_config *Config = Scratchpad->Config; + + 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 && + (First != 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 kbts_b32 kbts__ReadOp(kbts_shape_scratchpad *Scratchpad, kbts__op_kind End) +{ + KBTS_INSTRUMENT_FUNCTION_BEGIN; + kbts_b32 Result = 0; + kbts_shape_config *Config = Scratchpad->Config; + + if(Config) + { + kbts__op_list *OpList = &Config->OpList; + + if(Scratchpad->Ip < OpList->OpCount) + { + kbts__op_kind Kind = OpList->Ops[Scratchpad->Ip++]; + + // @Cleanup + if((Kind == KBTS__OP_KIND_GSUB_FEATURES_WITH_USER) || + (Kind == KBTS__OP_KIND_GSUB_FEATURES) || + (Kind == KBTS__OP_KIND_GPOS_FEATURES)) + { + Scratchpad->FeatureStagesRead += 1; + + if(Kind == KBTS__OP_KIND_GSUB_FEATURES_WITH_USER) + { + Kind = KBTS__OP_KIND_GSUB_FEATURES; + } + } + + 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; + kbts__pointer_bump_allocator Bump = kbts__PointerBumpAllocator(Memory); + + if(Font) + { + Result = kbts__PointerPushType(&Bump, 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); + + kbts_u16 *FeatureStageFirstLookupIndices = kbts__PointerPushArray(&Bump, kbts_u16, Result->OpList.FeatureStageCount + 1); + if(Memory) + { + KBTS__FOR(FeatureStageIndex, 0, Result->OpList.FeatureStageCount + 1) + { + FeatureStageFirstLookupIndices[FeatureStageIndex] = 0; + } + } + + if(ShapingTables[KBTS_SHAPING_TABLE_GSUB] || ShapingTables[KBTS_SHAPING_TABLE_GPOS]) + { // Initialize sequential lookups. + kbts_un GlyphCount = Font->Blob->GlyphCount; + + kbts_u32 *GlyphLookupMatrix = KBTS__POINTER_OFFSET(kbts_u32, Font->Blob, Font->Blob->GlyphLookupMatrixOffsetFromStartOfFile); + kbts_un GposLookupIndexOffset = Font->Blob->GposLookupIndexOffset; + + kbts__sequential_lookup *SequentialLookups = 0; + kbts_u32 *IdSequentialLookupMatrix = 0; + kbts_un SequentialLookupCount = 0; + + KBTS__FOR(Iter, 0, 2) + { + kbts_un ThisSequentialLookupCount = 0; + kbts_un FeatureStageIndex = 0; + + KBTS__FOR(OpIndex, 0, Result->OpList.OpCount) + { + kbts__op_kind Op = Result->OpList.Ops[OpIndex]; + kbts_b32 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 BakedFeatureLookupIndexCount = 0; + + kbts__baked_feature BakedFeatures[KBTS_MAX_SIMULTANEOUS_FEATURES]; + kbts_u16 BakedFeatureLookupIndicesRead[KBTS_MAX_SIMULTANEOUS_FEATURES]; + kbts_un BakedFeatureCount = 0; + + 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); + + // @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; + + if(BakedFeatureCount == KBTS_MAX_SIMULTANEOUS_FEATURES) + { + break; + } + } + } + + 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 = (1u << (FeatureId - 1)) & KBTS__GLYPH_FEATURE_MASK; + } + + BakedFeatures[BakedFeatureCount] = BakedFeature; + + BakedFeatureCount += 1; + BakedFeatureLookupIndexCount += BakedFeature.Count; + + if(BakedFeatureCount >= KBTS_MAX_SIMULTANEOUS_FEATURES) + { + break; + } + } + } + + KBTS__FOR(BakedFeatureIndex, 0, BakedFeatureCount) + { + BakedFeatureLookupIndicesRead[BakedFeatureIndex] = 0; + } + + kbts_u16 LastLowestLookupIndex = 0xFFFF; + kbts_un BakedFeatureLookupIndicesLeft = BakedFeatureLookupIndexCount; + while(BakedFeatureLookupIndicesLeft) + { + kbts_u16 LowestLookupIndex = 0xFFFF; + + 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; + } + } + } + + // Handle the case where a single lookup is part of multiple features. + kbts_u32 GlyphFilter = 0; + kbts_u32 SkipFlags = 0; + kbts_b32 DefaultEnabled = 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) + { + GlyphFilter |= BakedFeature->GlyphFilter; + SkipFlags |= BakedFeature->SkipFlags; + + BakedFeatureLookupIndicesRead[BakedFeatureIndex] += 1; + BakedFeatureLookupIndicesLeft -= 1; + + if(kbts__ContainsFeature(&FeatureStage->Features, BakedFeature->FeatureId)) + { + DefaultEnabled = 1; + } + } + } + } + + if(LowestLookupIndex != LastLowestLookupIndex) + { + if(Iter && Memory && DefaultEnabled) + { + kbts_un FlatLookupIndex = (ShapingTable == KBTS_SHAPING_TABLE_GSUB) ? LowestLookupIndex : (LowestLookupIndex + GposLookupIndexOffset); + KBTS__FOR(GlyphIndex, 0, GlyphCount) + { + kbts__matrix_index MatrixIndex = kbts__GlyphLookupMatrixIndex(FlatLookupIndex, GlyphIndex, GlyphCount); + if(GlyphLookupMatrix[MatrixIndex.WordIndex] & (1u << MatrixIndex.BitIndex)) + { + kbts__matrix_index SequentialMatrixIndex = kbts__IdSequentialLookupMatrixIndex(ThisSequentialLookupCount, GlyphIndex, SequentialLookupCount); + IdSequentialLookupMatrix[SequentialMatrixIndex.WordIndex] |= 1u << SequentialMatrixIndex.BitIndex; + } + } + } + + if(!Iter) + { + ThisSequentialLookupCount += 1; + } + else + { + kbts__sequential_lookup *SequentialLookup = &SequentialLookups[ThisSequentialLookupCount++]; + if(Memory) + { + SequentialLookup->GlyphFilter = GlyphFilter; + SequentialLookup->SkipFlags = SkipFlags; + SequentialLookup->LookupIndex = LowestLookupIndex; + } + } + } + + LastLowestLookupIndex = LowestLookupIndex; + } + } + + if(Iter && Memory) + { + FeatureStageFirstLookupIndices[FeatureStageIndex + 1] = (kbts_u16)ThisSequentialLookupCount; + } + + KBTS_ASSERT(FeatureStageIndex < Result->OpList.FeatureStageCount); + FeatureStageIndex += 1; + } + } + + if(!Iter) + { + // We have the sequential lookup count. We can allocate our stuff. + SequentialLookupCount = ThisSequentialLookupCount; + SequentialLookups = kbts__PointerPushArray(&Bump, kbts__sequential_lookup, SequentialLookupCount); + + kbts_un LastSequentialLookupIndex = 0; + if(SequentialLookupCount) + { + LastSequentialLookupIndex = SequentialLookupCount - 1; + } + kbts_un LastGlyphIndex = 0; + if(GlyphCount) + { + LastGlyphIndex = GlyphCount - 1; + } + + kbts__matrix_index LastMatrixIndex = kbts__IdSequentialLookupMatrixIndex(LastSequentialLookupIndex, LastGlyphIndex, SequentialLookupCount); + kbts_un IdSequentialLookupMatrixSizeInWords = LastMatrixIndex.WordIndex + 1; + kbts_un IdSequentialLookupMatrixSizeInBytes = sizeof(kbts_u32) * IdSequentialLookupMatrixSizeInWords; + IdSequentialLookupMatrix = (kbts_u32 *)kbts__PointerPush(&Bump, IdSequentialLookupMatrixSizeInBytes, KBTS_ALIGNOF(kbts_u32)); + if(Memory) + { + KBTS_MEMSET(IdSequentialLookupMatrix, 0, IdSequentialLookupMatrixSizeInBytes); + } + } + } + + if(Memory) + { + Result->SequentialLookups = SequentialLookups; + Result->IdSequentialLookupMatrix = IdSequentialLookupMatrix; + Result->GlyphCount = Font->Blob->GlyphCount; + Result->LookupCount = Font->Blob->LookupCount; + } + } + + if(Memory) + { + Result->FeatureStageFirstLookupIndices = FeatureStageFirstLookupIndices; + } + } + + if(!Memory) + { + // We add the align, just to make sure we can accept any incoming pointer. + *Size = (Bump.At - (kbts_uptr)(void *)0) + 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; + } + + 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; +} + + +KBTS_EXPORT int kbts_SizeOfGlyphConfig(kbts_shape_config *ShapeConfig, kbts_feature_override *Overrides, int OverrideCount) +{ + kbts_un NonBinaryOverrideCount = 0; + KBTS__FOR(OverrideIndex, 0, (kbts_un)OverrideCount) + { + kbts_feature_override *Override = &Overrides[OverrideIndex]; + + if(Override->Value > 1) + { + NonBinaryOverrideCount += 1; + } + } + + kbts_un SequentialLookupCount = kbts__SequentialLookupCount(ShapeConfig); + kbts_un LastSequentialLookupIndex = (SequentialLookupCount) ? (SequentialLookupCount - 1) : 0; + kbts__matrix_index LastRowEntryMatrixIndex = kbts__IdSequentialLookupMatrixIndex(LastSequentialLookupIndex, 0, SequentialLookupCount); + kbts_un MatrixRowSizeInBytes = sizeof(kbts_u32) * (LastRowEntryMatrixIndex.WordIndex + 1); + + kbts_un Result = sizeof(kbts_glyph_config) + + NonBinaryOverrideCount * sizeof(kbts__enabled_lookup) + + MatrixRowSizeInBytes * 2; + return (int)Result; +} + +KBTS_EXPORT kbts_glyph_config *kbts_PlaceGlyphConfig(kbts_shape_config *ShapeConfig, kbts_feature_override *Overrides, int OverrideCount, void *Memory) +{ + kbts__pointer_bump_allocator Bump = kbts__PointerBumpAllocator(Memory); + kbts_glyph_config *Result = kbts__PointerPushType(&Bump, kbts_glyph_config); + + if(Memory) + { + KBTS_MEMSET(Result, 0, sizeof(*Result)); + + kbts_un SequentialLookupCount = kbts__SequentialLookupCount(ShapeConfig); + kbts_un LastSequentialLookupIndex = (SequentialLookupCount) ? (SequentialLookupCount - 1) : 0; + kbts__matrix_index LastRowEntryMatrixIndex = kbts__IdSequentialLookupMatrixIndex(LastSequentialLookupIndex, 0, SequentialLookupCount); + kbts_un MatrixRowSizeInBytes = sizeof(kbts_u32) * (LastRowEntryMatrixIndex.WordIndex + 1); + kbts_u32 *EnabledLookupBits = (kbts_u32 *)kbts__PointerPush(&Bump, MatrixRowSizeInBytes, KBTS_ALIGNOF(kbts_u32)); + KBTS_MEMSET(EnabledLookupBits, 0, MatrixRowSizeInBytes); + kbts_u32 *DisabledLookupBits = (kbts_u32 *)kbts__PointerPush(&Bump, MatrixRowSizeInBytes, KBTS_ALIGNOF(kbts_u32)); + KBTS_MEMSET(DisabledLookupBits, 0, MatrixRowSizeInBytes); + + kbts__enabled_lookup NonBinaryEnabledLookups[KBTS_MAX_SIMULTANEOUS_FEATURES]; + kbts_un NonBinaryEnabledLookupCount = 0; + + kbts__feature_set OverriddenFeatures = KBTS__ZERO; + KBTS__FOR(OverrideIndex, 0, (kbts_un)OverrideCount) + { + kbts_feature_override *Override = &Overrides[OverrideIndex]; + kbts__AddFeature(&OverriddenFeatures, kbts__FeatureTagToId(Override->Tag)); + } + + KBTS__FOR(ShapingTable, 0, KBTS_SHAPING_TABLE_COUNT) + { + // @Duplication + kbts__gsub_gpos *GsubGpos = kbts__BlobTableDataType(ShapeConfig->Font->Blob, (ShapingTable == KBTS_SHAPING_TABLE_GSUB) ? KBTS_BLOB_TABLE_ID_GSUB : KBTS_BLOB_TABLE_ID_GPOS, kbts__gsub_gpos); + + kbts_un FirstSequentialLookupIndex = 0; + kbts_un OnePastLastSequentialLookupIndex = kbts__GsubSequentialLookupCount(ShapeConfig); + if(ShapingTable == KBTS_SHAPING_TABLE_GPOS) + { + FirstSequentialLookupIndex = OnePastLastSequentialLookupIndex; + OnePastLastSequentialLookupIndex = kbts__SequentialLookupCount(ShapeConfig); + } + + kbts_lookup_list *LookupList = kbts__GetLookupList(GsubGpos); + + kbts__iterate_features IterateFeatures = kbts__IterateFeatures(ShapeConfig, (kbts_shaping_table)ShapingTable, OverriddenFeatures); + + while(kbts__NextFeature(&IterateFeatures)) + { + kbts_feature_override *FoundOverride = 0; + + KBTS__FOR(OverrideIndex, 0, (kbts_un)OverrideCount) + { + kbts_feature_override *Override = &Overrides[OverrideIndex]; + + if(Override->Tag == IterateFeatures.CurrentFeatureTag) + { + FoundOverride = Override; + + break; + } + } + + // @Robustness: Why did we check for unregistered features here? + // if(!FoundOverride && + // (kbts__FeatureTagToId(IterateFeatures.CurrentFeatureTag) == KBTS__FEATURE_ID_UNREGISTERED)) + // { + // continue; + // } + if(FoundOverride) + { + kbts__iterate_lookups IterateLookups = kbts__IterateLookups(LookupList, IterateFeatures.Feature); + + while(kbts__NextLookup(&IterateLookups)) + { + kbts_u16 LookupIndex = IterateLookups.LookupIndex; + kbts_un FoundSequentialLookupIndex; + kbts_b32 Found = 0; + KBTS__FOR(SequentialLookupIndex, FirstSequentialLookupIndex, OnePastLastSequentialLookupIndex) + { + kbts__sequential_lookup *SequentialLookup = &ShapeConfig->SequentialLookups[SequentialLookupIndex]; + + if(SequentialLookup->LookupIndex == LookupIndex) + { + FoundSequentialLookupIndex = SequentialLookupIndex; + Found = 1; + + break; + } + } + + if(Found) + { + kbts__matrix_index SequentialMatrixIndex = kbts__IdSequentialLookupMatrixIndex(FoundSequentialLookupIndex, 0, SequentialLookupCount); + if(FoundOverride->Value) + { + EnabledLookupBits[SequentialMatrixIndex.WordIndex] |= 1u << SequentialMatrixIndex.BitIndex; + + if((FoundOverride->Value > 1) && + (NonBinaryEnabledLookupCount < KBTS_MAX_SIMULTANEOUS_FEATURES)) + { + kbts__enabled_lookup *NewEnabled = &NonBinaryEnabledLookups[NonBinaryEnabledLookupCount++]; + NewEnabled->SequentialLookupIndex = (kbts_u16)FoundSequentialLookupIndex; + NewEnabled->Value = (kbts_u16)FoundOverride->Value; + } + } + else + { + DisabledLookupBits[SequentialMatrixIndex.WordIndex] |= 1u << SequentialMatrixIndex.BitIndex; + } + } + } + } + } + } + + kbts__enabled_lookup *OutNonBinaryEnabledLookups = 0; + if(NonBinaryEnabledLookupCount) + { + OutNonBinaryEnabledLookups = kbts__PointerPushArray(&Bump, kbts__enabled_lookup, NonBinaryEnabledLookupCount); + KBTS_MEMCPY(OutNonBinaryEnabledLookups, NonBinaryEnabledLookups, sizeof(*NonBinaryEnabledLookups) * NonBinaryEnabledLookupCount); + } + + Result->NonBinaryEnabledLookups = OutNonBinaryEnabledLookups; + Result->NonBinaryEnabledLookupCount = (kbts_u32)NonBinaryEnabledLookupCount; + Result->EnabledLookupBits = EnabledLookupBits; + Result->DisabledLookupBits = DisabledLookupBits; + } + + kbts__feature_set OverriddenFeatures = KBTS__ZERO; + KBTS__FOR(OverrideIndex, 0, (kbts_un)OverrideCount) + { + kbts_feature_override *Override = &Overrides[OverrideIndex]; + kbts__AddFeature(&OverriddenFeatures, kbts__FeatureTagToId(Override->Tag)); + } + + return Result; +} + +KBTS_EXPORT kbts_glyph_config *kbts_CreateGlyphConfig(kbts_shape_config *ShapeConfig, kbts_feature_override *Overrides, int OverrideCount, kbts_allocator_function *Allocator, void *AllocatorData) +{ + if(!Allocator) + { + Allocator = kbts__DefaultAllocator; + } + + kbts_glyph_config *Result = kbts_PlaceGlyphConfig(ShapeConfig, Overrides, OverrideCount, kbts__AllocatorAllocate(Allocator, AllocatorData, (kbts_un)kbts_SizeOfGlyphConfig(ShapeConfig, 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; + + // Scratch features persist across frames. Don't reset ScratchFeatureOverrideCount. + Context->CurrentFeatureOverrides = 0; + Context->CurrentFeatureOverrideCount = 0; + Context->ExistingGlyphConfigCount = 0; + Context->NeedNewGlyphConfig = 1; + + Context->ParagraphDirection = ParagraphDirection; + Context->Language = Language; + + 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 = 1u << (KBTS__INPUT_CODEPOINT_FIRST_BLOCK_MSB + 1); + } + else + { + Result.BlockIndex = (kbts_u32)(MsbPosition - KBTS__INPUT_CODEPOINT_FIRST_BLOCK_MSB); + Result.CodepointIndex = (kbts_u32)(FlatCodepointIndex & ~(1u << MsbPosition)); + Result.BlockCodepointCount = (kbts_u32)(1u << 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 : (1u << (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_un NewFeatureOverrideCount = Context->ScratchFeatureOverrideCount; + + if(Context->ScratchFeatureOverrideCount) + { + kbts_feature_override UniqueFeatureOverrides[KBTS_MAX_SIMULTANEOUS_FEATURES]; + kbts_un UniqueFeatureOverrideCount = 0; + + for(kbts_un ScratchFeatureOverrideIndex = Context->ScratchFeatureOverrideCount; + ScratchFeatureOverrideIndex; + --ScratchFeatureOverrideIndex) + { + kbts_feature_override *ScratchOverride = &Context->ScratchFeatureOverrides[ScratchFeatureOverrideIndex - 1]; + kbts_u32 ScratchTag = ScratchOverride->Tag; + + kbts_b32 Dupe = 0; + KBTS__FOR(UniqueFeatureOverrideIndex, 0, UniqueFeatureOverrideCount) + { + kbts_feature_override *UniqueOverride = &UniqueFeatureOverrides[UniqueFeatureOverrideIndex]; + + if(UniqueOverride->Tag == ScratchTag) + { + Dupe = 1; + break; + } + } + + if(!Dupe) + { + UniqueFeatureOverrides[UniqueFeatureOverrideCount++] = *ScratchOverride; + } + } + + kbts_feature_override *Hoisted = kbts__PushArray(&Context->ScratchArena, kbts_feature_override, UniqueFeatureOverrideCount); + if(!Hoisted) + { + Context->Error = KBTS_SHAPE_ERROR_OUT_OF_MEMORY; + return; + } + KBTS_MEMCPY(Hoisted, Context->ScratchFeatureOverrides, sizeof(*Hoisted) * UniqueFeatureOverrideCount); + + Context->CurrentFeatureOverrides = Hoisted; + NewFeatureOverrideCount = UniqueFeatureOverrideCount; + } + + Context->CurrentFeatureOverrideCount = (kbts_u32)NewFeatureOverrideCount; + Context->NeedNewGlyphConfig = 0; + } + + { // Add the codepoint. + kbts_un FlatCodepointIndex = Context->InputCodepointCount; + kbts_shape_codepoint InputCodepoint = KBTS__ZERO; + InputCodepoint.Codepoint = Codepoint; + InputCodepoint.UserId = UserId; + InputCodepoint.FeatureOverrides = Context->CurrentFeatureOverrides; + InputCodepoint.FeatureOverrideCount = Context->CurrentFeatureOverrideCount; + + // @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) + { + if(Context->ScratchFeatureOverrideCount < KBTS__ARRAY_LENGTH(Context->ScratchFeatureOverrides)) + { + kbts_feature_override *Override = &Context->ScratchFeatureOverrides[Context->ScratchFeatureOverrideCount++]; + Override->Tag = Tag; + Override->Value = Value; + } + + Context->NeedNewGlyphConfig = 1; + } +} + +KBTS_EXPORT int kbts_ShapePopFeature(kbts_shape_context *Context, kbts_u32 Tag) +{ + int Result = 0; + + if(!Context->Error) + { + for(kbts_un ScratchFeatureOverrideIndex = Context->ScratchFeatureOverrideCount; + ScratchFeatureOverrideIndex; + --ScratchFeatureOverrideIndex) + { + kbts_feature_override *Override = &Context->ScratchFeatureOverrides[ScratchFeatureOverrideIndex - 1]; + + if(Override->Tag == Tag) + { + KBTS__FOR(MoveIndex, ScratchFeatureOverrideIndex, Context->ScratchFeatureOverrideCount) + { + Context->ScratchFeatureOverrides[ScratchFeatureOverrideIndex - 1] = Context->ScratchFeatureOverrides[ScratchFeatureOverrideIndex]; + } + + Context->ScratchFeatureOverrideCount -= 1; + break; + } + } + + if(Result) + { + Context->NeedNewGlyphConfig = 1; + } + } + + return Result; +} + +static void kbts__ShapeDirect(kbts_shape_scratchpad *Scratchpad, kbts_glyph_storage *Storage, kbts_direction RunDirection) +{ + KBTS_INSTRUMENT_FUNCTION_BEGIN; + + if(kbts__GlyphIsValid(Storage, Storage->GlyphSentinel.Next)) + { + Scratchpad->Ip = 0; + Scratchpad->FeatureStagesRead = 0; + Scratchpad->OpKind = 0; + Scratchpad->RunDirection = RunDirection; + Scratchpad->NextGlyphUid = 0; + Scratchpad->SequentialLookupIndexIndex = 0; + + { // @Cleanup @Speed + kbts_un SequentialLookupCount = kbts__SequentialLookupCount(Scratchpad->Config); + KBTS__FOR(LookupIndex, 0, SequentialLookupCount) + { + kbts__FreeGlyphBucket(Scratchpad, LookupIndex); + } + } + + KBTS_INSTRUMENT_BLOCK_BEGIN(ReadOpLoop0); + + // 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, KBTS__OP_KIND_BEGIN_CLUSTER)) + { + kbts__ExecuteOp(Scratchpad, Storage); + + if(Scratchpad->Error) + { + return; + } + } + + KBTS_INSTRUMENT_BLOCK_END(ReadOpLoop0); + + if(Scratchpad->OpKind == KBTS__OP_KIND_BEGIN_CLUSTER) + { + kbts_u32 BeginClusterSequentialLookupIndexIndex = Scratchpad->SequentialLookupIndexIndex; + kbts_u32 BeginClusterIp = Scratchpad->Ip; + kbts_u32 BeginClusterFeatureStagesRead = Scratchpad->FeatureStagesRead; + kbts_glyph *TopLevelGlyph = Storage->GlyphSentinel.Next; + + { // @Cleanup @Speed + // We have been bucketing all glyphs into cluster lookups. That's no good! + // For now, we zero all the buckets here and bucket the glyphs again, one cluster at a time. + kbts_un SequentialLookupCount = kbts__SequentialLookupCount(Scratchpad->Config); + KBTS__FOR(LookupIndex, BeginClusterSequentialLookupIndexIndex, SequentialLookupCount) + { + kbts__FreeGlyphBucket(Scratchpad, LookupIndex); + } + } + + Scratchpad->ClusterAtStartOfWord = 1; + + while(kbts__GlyphIsValid(Storage, TopLevelGlyph)) + { + kbts_b32 WordBreak = 0; + + Scratchpad->Ip = BeginClusterIp; + Scratchpad->FeatureStagesRead = BeginClusterFeatureStagesRead; + Scratchpad->SequentialLookupIndexIndex = BeginClusterSequentialLookupIndexIndex; + + { + // We need to store this in case TopLevelGlyph is reordered. + kbts_glyph *OneBeforeFirstClusterGlyph = TopLevelGlyph->Prev; + kbts_glyph *OnePastLastClusterGlyph = kbts__BeginCluster(Scratchpad, Storage, TopLevelGlyph); + + if(Scratchpad->Error) + { + return; + } + + WordBreak = !(OnePastLastClusterGlyph->Prev->UnicodeFlags & KBTS_UNICODE_FLAG_PART_OF_WORD); + Scratchpad->Cluster = kbts__PushGlyphList(Storage, OneBeforeFirstClusterGlyph->Next, OnePastLastClusterGlyph->Prev); + } + + // Bucket cluster glyphs for the first cluster op (or later). + KBTS__FOR_GLYPH(Storage, Glyph) + { + if(!kbts__BucketGlyph(Scratchpad, Glyph, BeginClusterSequentialLookupIndexIndex, 0)) + { + kbts__UnbucketGlyph(Scratchpad, Glyph); + } + } + + while(kbts__ReadOp(Scratchpad, KBTS__OP_KIND_END_CLUSTER)) + { + kbts__ExecuteOp(Scratchpad, Storage); + + if(Scratchpad->Error) + { + return; + } + } + + kbts__EndCluster(Scratchpad, Storage); + + while(kbts__ReadOp(Scratchpad, KBTS__OP_KIND_END_SYLLABLE)) + { + kbts__ExecuteOp(Scratchpad, Storage); + + if(Scratchpad->Error) + { + return; + } + } + + // 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, 0)) + { + kbts__ExecuteOp(Scratchpad, Storage); + + if(Scratchpad->Error) + { + return; + } + } + } + } + + KBTS_INSTRUMENT_FUNCTION_END; +} + +KBTS_EXPORT void kbts_DestroyShapeScratchpad(kbts_shape_scratchpad *Scratchpad) +{ + if(Scratchpad) + { + kbts_allocator_function *Allocator = Scratchpad->Allocator; + void *AllocatorData = Scratchpad->AllocatorData; + + // We cannot just free the blocks inline, because freeing a start-of-allocation block will + // invalidate a bunch of other, unrelated blocks. + // We first store all of the start-of-allocation blocks in this list, and we then free them all at the end. + kbts__bucketed_glyph_block_header StartOfAllocationSentinel; + KBTS__DLLIST_SENTINEL_INIT(&StartOfAllocationSentinel); + + kbts_un SequentialLookupCount = Scratchpad->SequentialLookupCount; + KBTS__FOR(LookupIndex, 0, SequentialLookupCount) + { + kbts__bucketed_glyph_block_header *Sentinel = &Scratchpad->LookupGlyphBuckets[LookupIndex]; + for(kbts__bucketed_glyph_block_header *Header = Sentinel->Next; + Header != Sentinel; + ) + { + kbts__bucketed_glyph_block_header *Next = Header->Next; + + kbts__bucketed_glyph_block *Block = (kbts__bucketed_glyph_block *)Header; + if(Block->StartOfAllocation) + { + KBTS__DLLIST_REMOVE(&Block->Header); + KBTS__DLLIST_INSERT_BEFORE(&Block->Header, &StartOfAllocationSentinel); + } + + Header = Next; + } + } + + for(kbts__bucketed_glyph_block_header *Header = Scratchpad->FreeBucketedBlockSentinel.Next; + Header != &Scratchpad->FreeBucketedBlockSentinel; + ) + { + kbts__bucketed_glyph_block_header *Next = Header->Next; + + kbts__bucketed_glyph_block *Block = (kbts__bucketed_glyph_block *)Header; + if(Block->StartOfAllocation) + { + KBTS__DLLIST_REMOVE(&Block->Header); + KBTS__DLLIST_INSERT_BEFORE(&Block->Header, &StartOfAllocationSentinel); + } + + Header = Next; + } + + for(kbts__bucketed_glyph_block_header *Header = StartOfAllocationSentinel.Next; + Header != &StartOfAllocationSentinel; + ) + { + kbts__bucketed_glyph_block_header *Next = Header->Next; + + kbts__AllocatorFree(Allocator, AllocatorData, Header); + + Header = Next; + } + + if(Scratchpad->SelfAllocated) + { + kbts__AllocatorFree(Allocator, AllocatorData, Scratchpad); + } + } +} + +KBTS_EXPORT kbts_shape_error kbts_ShapeDirect(kbts_shape_scratchpad *Scratchpad, kbts_glyph_storage *Storage, kbts_direction RunDirection, kbts_glyph_iterator *Output) +{ + kbts__ShapeDirect(Scratchpad, Storage, RunDirection); + kbts_shape_error Result = Scratchpad->Error; + + if(!Result) + { + *Output = kbts_ActiveGlyphIterator(Storage); + } + else + { + *Output = KBTS__ZERO_TYPE(kbts_glyph_iterator); + } + + 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); + } +} + +static kbts_shape_config *kbts__FindOrCreateShapeConfig(kbts_shape_context *Context, kbts_font *Font, kbts_script Script, kbts_language Language) +{ + kbts_shape_config *Result = 0; + + KBTS__FOR(ExistingConfigIndex, 0, Context->ExistingShapeConfigCount) + { + kbts__existing_shape_config *Existing = &Context->ExistingShapeConfigs[ExistingConfigIndex]; + + if((Existing->Font == Font) && + (Existing->Script == Script)) + { + Result = Existing->Config; + + break; + } + } + + if(!Result) + { + Result = kbts_CreateShapeConfig(Font, Script, Language, kbts__ArenaAllocator, &Context->ScratchArena); + + if(Context->ExistingShapeConfigCount < KBTS__ARRAY_LENGTH(Context->ExistingShapeConfigs)) + { + kbts__existing_shape_config *NewExisting = &Context->ExistingShapeConfigs[Context->ExistingShapeConfigCount++]; + + NewExisting->Config = Result; + NewExisting->Font = Font; + NewExisting->Script = Script; + } + } + + return Result; +} + +static kbts_glyph_config *kbts__FindOrCreateGlyphConfig(kbts_shape_context *Context, kbts_shape_config *ShapeConfig, kbts_feature_override *FeatureOverrides, int FeatureOverrideCount) +{ + kbts_glyph_config *Result = 0; + + if(FeatureOverrideCount) + { + KBTS__FOR(ExistingGlyphConfigIndex, 0, Context->ExistingGlyphConfigCount) + { + kbts__existing_glyph_config *Existing = &Context->ExistingGlyphConfigs[ExistingGlyphConfigIndex]; + + if((Existing->FeatureOverrides == FeatureOverrides) && + (Existing->FeatureOverrideCount == FeatureOverrideCount)) + { + Result = Existing->GlyphConfig; + + break; + } + } + + if(!Result) + { + Result = kbts_CreateGlyphConfig(ShapeConfig, FeatureOverrides, FeatureOverrideCount, kbts__ArenaAllocator, &Context->ScratchArena); + + if(Context->ExistingGlyphConfigCount < KBTS__ARRAY_LENGTH(Context->ExistingGlyphConfigs)) + { + kbts__existing_glyph_config *Existing = &Context->ExistingGlyphConfigs[Context->ExistingGlyphConfigCount++]; + Existing->FeatureOverrides = FeatureOverrides; + Existing->FeatureOverrideCount = FeatureOverrideCount; + Existing->GlyphConfig = Result; + } + } + } + + return Result; +} + +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; + kbts_shape_config *ShapeConfig = 0; + + 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 = (1u << (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; + + // Initialize the shape_config now, before pushing glyphs. + ShapeConfig = kbts__FindOrCreateShapeConfig(Context, RunFont, RunScript, Language); + + kbts_glyph_config *GlyphConfig = kbts__FindOrCreateGlyphConfig(Context, ShapeConfig, InputCodepoint->FeatureOverrides, InputCodepoint->FeatureOverrideCount); + kbts_PushGlyph(&Context->GlyphStorage, RunFont, InputCodepoint->Codepoint, GlyphConfig, InputCodepointIndex); + + Initialized = 1; + } + } + else + { + // This is an exceptional case, but it can happen when we detect no script. + if(!ShapeConfig) + { + ShapeConfig = kbts__FindOrCreateShapeConfig(Context, RunFont, RunScript, Language); + } + + kbts_glyph_config *GlyphConfig = kbts__FindOrCreateGlyphConfig(Context, ShapeConfig, InputCodepoint->FeatureOverrides, InputCodepoint->FeatureOverrideCount); + kbts_PushGlyph(&Context->GlyphStorage, RunFont, InputCodepoint->Codepoint, GlyphConfig, InputCodepointIndex); + } + } + + FoundBreak:; + + if(Result) + { + if(!RunDirection) + { + RunDirection = KBTS_DIRECTION_LTR; + + if((ShapeConfig->Shaper == KBTS_SHAPER_ARABIC) || + (ShapeConfig->Shaper == KBTS_SHAPER_HEBREW)) + { + RunDirection = KBTS_DIRECTION_RTL; + } + } + + // @Memory: Store this alongside the shape_config! + kbts_un ScratchpadSize = kbts_SizeOfShapeScratchpad(ShapeConfig); + kbts_shape_scratchpad *Scratchpad = kbts_PlaceShapeScratchpad(ShapeConfig, kbts__PushSize(&Context->ScratchArena, ScratchpadSize, 8), kbts__ArenaAllocator, &Context->ScratchArena); + + kbts__ShapeDirect(Scratchpad, &Context->GlyphStorage, RunDirection); + + 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 = kbts__ReadU16Unaligned(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); + kbts__WriteU16Unaligned(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; + + 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; + } + + kbts_un 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 GlyphLookupMatrixSizeInWords = 0; + if(State->LookupCount && + State->GlyphCount) + { + kbts__matrix_index LastIndex = kbts__GlyphLookupMatrixIndex(State->LookupCount - 1, State->GlyphCount - 1, State->GlyphCount); + GlyphLookupMatrixSizeInWords = LastIndex.WordIndex + 1; + } + + kbts_un GlyphLookupSubtableMatrixSizeInWords = 0; + if(State->LookupSubtableCount && + State->GlyphCount) + { + kbts__matrix_index LastIndex = kbts__GlyphLookupSubtableMatrixIndex(State->LookupSubtableCount - 1, State->LookupSubtableCount, State->GlyphCount - 1, State->GlyphCount); + GlyphLookupSubtableMatrixSizeInWords = LastIndex.WordIndex + 1; + } + + kbts__pointer_bump_allocator Bump = kbts__PointerBumpAllocator(0); + + kbts__PointerPushType(&Bump, kbts_blob_header); + + KBTS__FOR(TableId, 0, KBTS_BLOB_TABLE_ID_COUNT) + { + kbts__PointerPush(&Bump, State->Tables[TableId].Length, 4); + } + + kbts__PointerPushArray(&Bump, kbts_u32, GlyphLookupMatrixSizeInWords); + kbts__PointerPushArray(&Bump, kbts_u32, GlyphLookupSubtableMatrixSizeInWords); + kbts__PointerPushArray(&Bump, kbts_u32, State->LookupCount); + + // Add the align just to make sure we can accept any pointer. + kbts_un OutputSize = Bump.At + KBTS_ALIGNOF(kbts_blob_header); + + *ScratchSize_ = (int)ScratchSize; + *OutputSize_ = (int)OutputSize; + + State->ScratchSize = (kbts_u32)ScratchSize; + State->GlyphLookupMatrixSizeInBytes = (kbts_u32)(GlyphLookupMatrixSizeInWords * sizeof(kbts_u32)); + State->GlyphLookupSubtableMatrixSizeInBytes = (kbts_u32)(GlyphLookupSubtableMatrixSizeInWords * sizeof(kbts_u32)); + 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, GlyphCount) : + kbts__GlyphLookupMatrixIndex(TableIndex, GlyphId, GlyphCount); + + if(GlyphId < GlyphCount) + { + Matrix[MatrixIndex.WordIndex] |= 1u << 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, GlyphCount) : + kbts__GlyphLookupMatrixIndex(TableIndex, GlyphId, GlyphCount); + + if(GlyphId < GlyphCount) + { + Matrix[MatrixIndex.WordIndex] |= 1u << 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, GlyphCount); + Matrix[SubtableMatrixIndex.WordIndex] |= 1u << 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, GlyphCount); + Matrix[SubtableMatrixIndex.WordIndex] |= 1u << 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__pointer_bump_allocator Bump = kbts__PointerBumpAllocator(OutputMemory); + + kbts_blob_header *Header = kbts__PointerPushType(&Bump, kbts_blob_header); + *Header = KBTS__ZERO_TYPE(kbts_blob_header); + Header->Magic = KBTS_FOURCC('k', 'b', 't', 's'); + Header->Version = KBTS_BLOB_VERSION_CURRENT; + Header->LookupCount = State->LookupCount; + Header->LookupSubtableCount = State->LookupSubtableCount; + + // Stamp packed font data. + KBTS__FOR(TableId, 0, KBTS_BLOB_TABLE_ID_COUNT) + { + kbts_blob_table InTable = State->Tables[TableId]; + kbts_blob_table *OutTable = &Header->Tables[TableId]; + + char *TableBase = (char *)kbts__PointerPush(&Bump, InTable.Length, 4); + OutTable->OffsetFromStartOfFile = KBTS__POINTER_DIFF32(TableBase, Header); + OutTable->Length = InTable.Length; + + void *InData = KBTS__POINTER_OFFSET(void, State->FontData, InTable.OffsetFromStartOfFile); + KBTS_MEMCPY(TableBase, InData, 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) + { + kbts_u16 SubtableFormat = kbts__ReadU16Unaligned(PreferredSubtable.Subtable); + switch(SubtableFormat) + { + 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_un CoverageOffset = kbts__ReadU32Unaligned(&CoverageOffsets[MarkGlyphSetIndex]); + kbts__coverage *Coverage = KBTS__POINTER_OFFSET(kbts__coverage, MarkGlyphSets, CoverageOffset); + 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__PointerPushArray(&Bump, kbts_u32, State->GlyphLookupMatrixSizeInBytes / sizeof(kbts_u32)); + kbts_u32 *GlyphLookupSubtableMatrix = kbts__PointerPushArray(&Bump, kbts_u32, State->GlyphLookupSubtableMatrixSizeInBytes / sizeof(kbts_u32)); + kbts_u32 *LookupSubtableIndexOffsets = kbts__PointerPushArray(&Bump, kbts_u32, State->LookupCount); + + KBTS_MEMSET(GlyphLookupMatrix, 0, State->GlyphLookupMatrixSizeInBytes); + KBTS_MEMSET(GlyphLookupSubtableMatrix, 0, State->GlyphLookupSubtableMatrixSizeInBytes); + KBTS_MEMSET(LookupSubtableIndexOffsets, 0, sizeof(kbts_u32) * State->LookupCount); + + 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(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_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, GlyphCount); + GlyphLookupSubtableMatrix[SubtableMatrixIndex.WordIndex] |= 1u << SubtableMatrixIndex.BitIndex; + } + } + } + } + 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); + + 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, GlyphCount); + GlyphLookupSubtableMatrix[SubtableMatrixIndex.WordIndex] |= 1u << 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); + + 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); + + 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); + + KBTS__FOR(BacktrackIndex, 0, Unpacked.BacktrackCount) + { + kbts_un GlyphId = Unpacked.Backtrack[BacktrackIndex]; + kbts__matrix_index SubtableMatrixIndex = kbts__GlyphLookupSubtableMatrixIndex(RunningSubtableIndex, SubtableCount, GlyphId, GlyphCount); + GlyphLookupSubtableMatrix[SubtableMatrixIndex.WordIndex] |= 1u << SubtableMatrixIndex.BitIndex; + } + + KBTS__FOR(InputIndex, 1, Unpacked.InputCount) + { + kbts_un GlyphId = Unpacked.Input[InputIndex - 1]; + kbts__matrix_index SubtableMatrixIndex = kbts__GlyphLookupSubtableMatrixIndex(RunningSubtableIndex, SubtableCount, GlyphId, GlyphCount); + GlyphLookupSubtableMatrix[SubtableMatrixIndex.WordIndex] |= 1u << SubtableMatrixIndex.BitIndex; + } + + KBTS__FOR(LookaheadIndex, 0, Unpacked.LookaheadCount) + { + kbts_un GlyphId = Unpacked.Lookahead[LookaheadIndex]; + kbts__matrix_index SubtableMatrixIndex = kbts__GlyphLookupSubtableMatrixIndex(RunningSubtableIndex, SubtableCount, GlyphId, GlyphCount); + GlyphLookupSubtableMatrix[SubtableMatrixIndex.WordIndex] |= 1u << 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); + + 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]); + + 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); + + 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); + + RunningSubtableIndex += 1; + } + + RunningLookupIndex += 1; + } + } + + if(!InGpos) + { + GposLookupIndexOffset = RunningLookupIndex; + } + } + } + + 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); + } + } + + if(Result != KBTS_LOAD_FONT_ERROR_NONE) + { + Font->Blob = 0; + } + Font->Error = Result; + + return Result; +} + +KBTS_EXPORT void kbts_GetFontInfo2(kbts_font *Font, kbts_font_info2 *Info) +{ + if(Info && Info->Size) + { + kbts_un InfoSize = Info->Size; + KBTS_MEMSET(Info, 0, InfoSize); + Info->Size = (kbts_u32)InfoSize; + + kbts_blob_header *Blob = Font->Blob; + + if(Font && kbts_FontIsValid(Font) && Blob) + { + kbts__name *Name = kbts__BlobTableDataType(Blob, KBTS_BLOB_TABLE_ID_NAME, kbts__name); + kbts__os2 *Os2 = kbts__BlobTableDataType(Blob, KBTS_BLOB_TABLE_ID_OS2, kbts__os2); + // @Incomplete: Support vhea, too. + kbts__hea *Hhea = kbts__BlobTableDataType(Blob, KBTS_BLOB_TABLE_ID_HHEA, kbts__hea); + kbts__head *Head = kbts__BlobTableDataType(Blob, KBTS_BLOB_TABLE_ID_HEAD, kbts__head); + + switch(InfoSize) + { + case sizeof(kbts_font_info2_2): + { + kbts_font_info2_2 *Info2_2 = (kbts_font_info2_2 *)Info; + + if(Os2) + { + Info2_2->CapitalHeight = Os2->CapHeight; + } + } // Fallthrough + + case sizeof(kbts_font_info2_1): + { + kbts_font_info2_1 *Info2_1 = (kbts_font_info2_1 *)Info; + + if(Os2) + { + Info2_1->Ascent = Os2->TypoAscender; + Info2_1->Descent = Os2->TypoDescender; + Info2_1->LineGap = Os2->TypoLineGap; + } + else if(Hhea) + { + Info2_1->Ascent = Hhea->Ascent; + Info2_1->Descent = Hhea->Descent; + Info2_1->LineGap = Hhea->LineGap; + } + + if(Head) + { + Info2_1->UnitsPerEm = Head->UnitsPerEm; + + Info2_1->XMin = Head->XMin; + Info2_1->YMin = Head->YMin; + Info2_1->XMax = Head->XMax; + Info2_1->YMax = Head->YMax; + } + } // Fallthrough + + case sizeof(kbts_font_info2): + { + if(Name) + { + 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]; + } + } + + if(Os2) + { + 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; + } + } break; + } + } + } +} + +KBTS_EXPORT void kbts_GetFontInfo(kbts_font *Font, kbts_font_info *Info) +{ + kbts_font_info2 Info2; + Info2.Size = sizeof(Info2); + + kbts_GetFontInfo2(Font, &Info2); + + KBTS_MEMCPY(Info, Info2.Strings, sizeof(*Info)); +} + +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) (((1u << ((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; +} + +#endif +#undef KBTS_X_FEATURES diff --git a/vendors/kb_text_shape/kb_text_shape_impl.c b/vendors/kb_text_shape/kb_text_shape_impl.c new file mode 100644 index 0000000..e9cb547 --- /dev/null +++ b/vendors/kb_text_shape/kb_text_shape_impl.c @@ -0,0 +1,2 @@ +#define KB_TEXT_SHAPE_IMPLEMENTATION +#include "kb/kb_text_shape.h"