From c067cc03571d9bb9c02954d4aa33eefba3d092c0 Mon Sep 17 00:00:00 2001 From: penguindark <57967770+penguindark@users.noreply.github.com> Date: Sun, 10 Jan 2021 19:14:41 +0100 Subject: [PATCH] vlib: add a TTF font loader and render in `x.ttf` (#7995) --- .github/workflows/ci.yml | 8 +- cmd/tools/modules/testing/common.v | 5 +- examples/ttf_font/Graduate-Regular.ttf | Bin 0 -> 21292 bytes examples/ttf_font/Imprima-Regular.ttf | Bin 0 -> 23188 bytes examples/ttf_font/OFL.txt | 93 ++ examples/ttf_font/example_ttf.v | 202 +++++ vlib/x/ttf/common.v | 184 ++++ vlib/x/ttf/render_bmp.v | 818 +++++++++++++++++ vlib/x/ttf/render_sokol_cpu.v | 234 +++++ vlib/x/ttf/text_block.v | 122 +++ vlib/x/ttf/ttf.v | 1115 ++++++++++++++++++++++++ vlib/x/ttf/ttf_test.v | 242 +++++ 12 files changed, 3021 insertions(+), 2 deletions(-) create mode 100644 examples/ttf_font/Graduate-Regular.ttf create mode 100644 examples/ttf_font/Imprima-Regular.ttf create mode 100644 examples/ttf_font/OFL.txt create mode 100644 examples/ttf_font/example_ttf.v create mode 100644 vlib/x/ttf/common.v create mode 100644 vlib/x/ttf/render_bmp.v create mode 100644 vlib/x/ttf/render_sokol_cpu.v create mode 100644 vlib/x/ttf/text_block.v create mode 100644 vlib/x/ttf/ttf.v create mode 100644 vlib/x/ttf/ttf_test.v diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1d230b2f47..a915d29561 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -147,9 +147,15 @@ jobs: - name: Build V run: | make CC=clang + - name: Show PWD and Environment + run: | + echo "PWD:" + pwd + echo "ENVIRONMENT" + env - name: Test V fixed tests run: | - v -silent test-fixed + ./v -silent test-fixed macos: runs-on: macOS-latest diff --git a/cmd/tools/modules/testing/common.v b/cmd/tools/modules/testing/common.v index 2b541b34dd..481ae7dd7c 100644 --- a/cmd/tools/modules/testing/common.v +++ b/cmd/tools/modules/testing/common.v @@ -122,13 +122,16 @@ pub fn new_test_session(_vargs string) TestSession { } if github_job != 'ubuntu-tcc' { skip_files << 'examples/wkhtmltopdf.v' // needs installation of wkhtmltopdf from https://github.com/wkhtmltopdf/packaging/releases + // the ttf_test.v is not interactive, but needs X11 headers to be installed, which is done only on ubuntu-tcc for now + skip_files << 'vlib/x/ttf/ttf_test.v' } vargs := _vargs.replace('-progress', '').replace('-progress', '') vexe := pref.vexe_path() + vroot := os.dir(vexe) new_vtmp_dir := setup_new_vtmp_folder() return TestSession{ vexe: vexe - vroot: os.dir(vexe) + vroot: vroot skip_files: skip_files vargs: vargs vtmp_dir: new_vtmp_dir diff --git a/examples/ttf_font/Graduate-Regular.ttf b/examples/ttf_font/Graduate-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..0ce68b728d880e04670da9dc91627ef7ae2dd2d6 GIT binary patch literal 21292 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 Mg7^Kh?k6q#KPXDMbpQYW literal 0 HcmV?d00001 diff --git a/examples/ttf_font/Imprima-Regular.ttf b/examples/ttf_font/Imprima-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..9c701e12d3cabc889e9462ba595f5599eb6d95f3 GIT binary patch literal 23188 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 Wv8w>6) % 2 == 0 { + //txt1.align = .left + txt1.bmp.justify = true + } + + txt1.bmp.align = .left + if (app.frame_c>>6) % 3 == 0 { + txt1.bmp.align = .right + } + txt1.destroy_texture() + txt1.create_text_block(block_txt, 500, 500, 32) + txt1.create_texture() + } + + // decomment if want block color change + //txt1.bmp.color = ttf.color_multiply(0xFF00FFFF, f32(app.frame_c % 255)/255.0) + + // decomment if want block rotation wanted + //txt1.bmp.angle = 3.141592/180 * f32(app.frame_c % 45) + + txt1.draw_text_bmp(app.gg, 30 + (app.frame_c>>1) & 0xFF , 200) + + // draw mouse position + if app.mouse_x >= 0 { + txt1 = &app.ttf_render[2] + txt1.destroy_texture() + txt1.create_text("$app.mouse_x,$app.mouse_y",25) + txt1.create_texture() + r := app.mouse_x % 255 + g := app.mouse_y % 255 + color := u32(r << 24) | u32(g << 16) | 0xFF + txt1.bmp.color = color + txt1.draw_text_bmp(app.gg, app.mouse_x , app.mouse_y) + } + + app.frame_c ++ + } + + app.gg.end() +} + +fn my_event_manager(mut ev sapp.Event, mut app &App_data) { + if ev.typ == .mouse_move { + app.mouse_x = int(ev.mouse_x) + app.mouse_y = int(ev.mouse_y) + } +} + +[console] +fn main(){ + + mut app := &App_data{ + gg: 0 + } + + app.gg = gg.new_context({ + width: win_width + height: win_height + use_ortho: true // This is needed for 2D drawing + create_window: true + window_title: 'Test TTF module' + user_data: app + bg_color: bg_color + frame_fn: draw_frame + event_fn: my_event_manager + init_fn: my_init + }) + + // load TTF fonts + for font_path in font_paths { + mut tf := ttf.TTF_File{} + tf.buf = os.read_bytes(font_path) or { panic(err) } + println("TrueTypeFont file [$font_path] len: ${tf.buf.len}") + tf.init() + println("Unit per EM: $tf.units_per_em") + app.tf << tf + } + + // TTF render 0 Frame counter + app.ttf_render << &ttf.TTF_render_Sokol { + bmp: &ttf.BitMap{ + tf: &(app.tf[0]) + buf: malloc(32000000) + buf_size: (32000000) + color : 0xFF0000FF + //style: .raw + //use_font_metrics: true + } + } + + // TTF render 1 Text Block + app.ttf_render << &ttf.TTF_render_Sokol { + bmp: &ttf.BitMap{ + tf: &(app.tf[1]) + //color : 0xFF0000_10 + //style: .raw + //use_font_metrics: true + } + } + + // TTF mouse position render + app.ttf_render << &ttf.TTF_render_Sokol { + bmp: &ttf.BitMap{ + tf: &(app.tf[0]) + } + } + + /* setup sokol_gfx */ + app.gg.run() +} diff --git a/vlib/x/ttf/common.v b/vlib/x/ttf/common.v new file mode 100644 index 0000000000..25ec6eb8ed --- /dev/null +++ b/vlib/x/ttf/common.v @@ -0,0 +1,184 @@ +module ttf +/********************************************************************** +* +* Common data for the module +* +* Copyright (c) 2021 Dario Deledda. All rights reserved. +* Use of this source code is governed by an MIT license +* that can be found in the LICENSE file. +* +* Note: +* +* TODO: +**********************************************************************/ +import os +import math + +// text align +pub +enum Text_align { + left + center + right + justify +} + +// draw style +pub +enum Style { + outline + outline_aliased + filled + raw +} + +/****************************************************************************** +* +* DEBUG Utility +* +******************************************************************************/ +const debug_flag = false +fn dprintln(txt string){ + if debug_flag { + println(txt) + } +} + +/****************************************************************************** +* +* Utility +* +******************************************************************************/ +// write out a .ppm file +pub +fn (mut bmp BitMap) save_as_ppm(file_name string) { + npixels := bmp.width * bmp.height + mut f_out := os.create(file_name) or { panic(err) } + f_out.writeln('P3') + f_out.writeln('${bmp.width} ${bmp.height}') + f_out.writeln('255') + for i in 0..npixels { + pos := i * bmp.bp + unsafe { + c_r := 0xFF - bmp.buf[pos] + c_g := 0xFF - bmp.buf[pos +1 ] + c_b := 0xFF - bmp.buf[pos + 2] + f_out.write_str('${c_r} ${c_g} ${c_b} ') + } + + } + f_out.close() +} + +pub +fn (mut bmp BitMap) get_raw_bytes() []byte { + mut f_buf := []byte{len: bmp.buf_size/4} + mut i:=0 + for i < bmp.buf_size { + unsafe { f_buf[i>>2] = *(bmp.buf + i) } + i += 4 + } + return f_buf +} + +pub +fn (mut bmp BitMap) save_raw_data(file_name string) { + os.write_file_array(file_name, bmp.get_raw_bytes()) +} + + +// +// Math functions +// +[inline] +fn abs(a int) int { + if a < 0 { + return -a + } else { + return a + } +} + +[inline] +fn fabs(a f32) f32 { + if a < 0 { + return -a + } else { + return a + } +} + +// integer part of x +[inline] +fn ipart(x f32) f32 { + return f32(math.floor(x)) +} + +[inline] +fn round(x f32) f32 { + return ipart(x + 0.5) +} + +// fractional part of x +[inline] +fn fpart(x f32) f32 { + return x - f32(math.floor(x)) +} + +[inline] +fn rfpart(x f32) f32 { + return 1 - fpart(x) +} + +/****************************************************************************** +* +* Colors +* +******************************************************************************/ +/* +[inline] +pub +fn (mut dev BitMap) get_color(x int, y int) (int, int, int, int){ + if x < 0 || x >= dev.width || y < 0 || y >= dev.height { + return 0,0,0,0 + } + mut i := (x + y * dev.width)*dev.bp + unsafe{ + return dev.buf[i], dev.buf[i+1], dev.buf[i+2], dev.buf[i+3] + } +} + +[inline] +pub +fn (mut dev BitMap) get_color_u32(x int, y int) u32{ + r, g, b, a := dev.get_color(x, y) + unsafe{ + return u32(r<<24) | u32(g<<16) | u32(b<<8) | u32(a) + } +} +*/ +/****************************************************************************** +* +* Drawing +* +******************************************************************************/ +[inline] +pub +fn color_multiply_alpha(c u32, level f32) u32 { + return u32(f32( c & 0xFF) * level) +} + +[inline] +pub +fn color_multiply(c u32, level f32) u32 { + mut r := (f32((c >> 24) & 0xFF)/255.0) * level + mut g := (f32((c >> 16) & 0xFF)/255.0) * level + mut b := (f32((c >> 8) & 0xFF)/255.0) * level + mut a := (f32( c & 0xFF)/255.0) * level + r = if r > 1.0 { 1.0 } else { r } + g = if g > 1.0 { 1.0 } else { g } + b = if b > 1.0 { 1.0 } else { b } + a = if a > 1.0 { 1.0 } else { a } + + return (u32(r * 255) << 24) | (u32(g * 255) << 16) | (u32(b * 255) << 8) | u32(a * 255) +} \ No newline at end of file diff --git a/vlib/x/ttf/render_bmp.v b/vlib/x/ttf/render_bmp.v new file mode 100644 index 0000000000..9aa3296d34 --- /dev/null +++ b/vlib/x/ttf/render_bmp.v @@ -0,0 +1,818 @@ +module ttf +/********************************************************************** +* +* BMP render module utility functions +* +* Copyright (c) 2021 Dario Deledda. All rights reserved. +* Use of this source code is governed by an MIT license +* that can be found in the LICENSE file. +* +* Note: +* +* TODO: +* - manage text directions R to L +**********************************************************************/ +import encoding.utf8 +import math + +pub +struct BitMap { +pub mut: + tf &TTF_File + + buf byteptr // pointer to the memory buffer + buf_size int // allocated buf size in bytes + + width int =1 // width of the buffer + height int =1 // height of the buffer + bp int =4 // byte per pixel of the buffer + + bg_color u32 = 0xFFFFFF_00 // background RGBA format + color u32 = 0x000000_FF // RGBA format + scale f32 = 1.0 // internal usage!! + scale_x f32 = 1.0 // X scale of the single glyph + scale_y f32 = 1.0 // Y scale of the single glyph + angle f32 = 0.0 // angle of rotation of the bitmap + + // spaces + space_cw f32 = 1.0 // width of the space glyph internal usage!! + space_mult f32 = f32(0.0) //1.0/16.0 // space between letter, is a multiplier for a standrd space ax + + // used only by internal text rendering!! + tr_matrix []f32 = [f32(1), 0, 0, 0, 1, 0, 0, 0, 0] // transformation matrix + ch_matrix []f32 = [f32(1), 0, 0, 0, 1, 0, 0, 0, 0] // character matrix + + style Style = .filled // default syle + align Text_align = .left // default text align + justify bool // justify text flag, default deactivated + justify_fill_ratio f32 = 0.5 // justify fill ratio, if the ratio of the filled row is >= of this then justify the text + + filler [][]int // filler buffer for the renderer + + // flag to force font embedded metrics + use_font_metrics bool +} + +/****************************************************************************** +* +* Utility +* +******************************************************************************/ +// clear clear the bitmap with 0 bytes +pub +fn (mut bmp BitMap) clear() { + mut sz := bmp.width * bmp.height * bmp.bp + unsafe { + C.memset(bmp.buf, 0x00, sz) + } +} + +// transform matrix applied to the text +fn (bmp &BitMap) trf_txt(p &Point) (int, int) { + return int(p.x * bmp.tr_matrix[0] + p.y * bmp.tr_matrix[3] + bmp.tr_matrix[6]), + int(p.x * bmp.tr_matrix[1] + p.y * bmp.tr_matrix[4] + bmp.tr_matrix[7]) +} + +// transform matrix applied to the char +fn (bmp &BitMap) trf_ch(p &Point) (int, int) { + return int(p.x * bmp.ch_matrix[0] + p.y * bmp.ch_matrix[3] + bmp.ch_matrix[6]), + int(p.x * bmp.ch_matrix[1] + p.y * bmp.ch_matrix[4] + bmp.ch_matrix[7]) +} + +// set draw postion in the buffer +pub +fn (mut bmp BitMap) set_pos(x f32, y f32) { + bmp.tr_matrix[6] = x + bmp.tr_matrix[7] = y +} + +// set the rotation angle in radiants +pub +fn (mut bmp BitMap) set_rotation(a f32) { + bmp.tr_matrix[0] = f32(math.cos(a)) //1 + bmp.tr_matrix[1] = f32(-math.sin(a)) //0 + bmp.tr_matrix[3] = f32(math.sin(a)) //0 + bmp.tr_matrix[4] = f32(math.cos(a)) //1 +} + +/****************************************************************************** +* +* Filler functions +* +******************************************************************************/ +pub +fn (mut bmp BitMap) init_filler() { + h := bmp.height - bmp.filler.len + if h < 1 { + return + } + for _ in 0..h { + bmp.filler << []int{len:4} + } + // dprintln("Init filler: ${bmp.filler.len} rows") +} + +pub +fn (mut bmp BitMap) clear_filler() { + for i in 0..bmp.height { + bmp.filler[i].clear() + } +} + +pub +fn (mut bmp BitMap) exec_filler() { + for y in 0..bmp.height { + if bmp.filler[y].len > 0 { + bmp.filler[y].sort() + if bmp.filler[y].len & 1 != 0 { + //dprintln("even line!! $y => ${bmp.filler[y]}") + continue + } + mut index := 0 + for index < bmp.filler[y].len { + startx := bmp.filler[y][index] + 1 + endx := bmp.filler[y][index+1] + if startx >= endx { + index += 2 + continue + } + for x in startx..endx { + bmp.plot(x, y, bmp.color) + } + index += 2 + } + } + } +} + +pub +fn (mut bmp BitMap) fline(in_x0 int, in_y0 int, in_x1 int, in_y1 int, c u32) { + mut x0 := f32(in_x0) + mut x1 := f32(in_x1) + mut y0 := f32(in_y0) + mut y1 := f32(in_y1) + mut tmp := f32(0) + + // check bounds + if (in_x0 < 0 && in_x1 < 0) || (in_x0 > bmp.width && in_x1 > bmp.width) { + return + } + + if y1 < y0 { + tmp = x0 + x0 = x1 + x1 = tmp + + tmp = y0 + y0 = y1 + y1 = tmp + } + + mut dx := x1 - x0 + mut dy := y1 - y0 + + if dy == 0 { + if in_y0 >= 0 && in_y0 < bmp.filler.len { + if in_x0 <= in_x1 { + bmp.filler[in_y0] << in_x0 + bmp.filler[in_y0] << in_x1 + } else { + bmp.filler[in_y0] << in_x1 + bmp.filler[in_y0] << in_x0 + } + } + return + } + mut n := dx / dy + for y in 0..int(dy+0.5) { + yd := int(y + y0) + x := n * y + x0 + if x > bmp.width || yd >= bmp.filler.len { + break + } + if yd >= 0 && yd < bmp.filler.len { + bmp.filler[yd] << int(x+0.5) + //bmp.plot(int(x+0.5), yd, bmp.color) + } + } +} + +/****************************************************************************** +* +* Draw functions +* +******************************************************************************/ +[inline] +pub +fn (mut bmp BitMap) plot(x int, y int, c u32) bool { + if x < 0 || x >= bmp.width || y < 0 || y >= bmp.height { + return false + } + mut index := (x + y * bmp.width) * bmp.bp + unsafe { + //bmp.buf[index]=0xFF + bmp.buf[index] = byte(c & 0xFF) // write only the alpha + } +/* + for count in 0..(bmp.bp) { + unsafe{ + bmp.buf[index + count] = byte((c >> (bmp.bp - count - 1) * 8) & 0x0000_00FF) + } + } +*/ + return true +} + +/****************************************************************************** +* +* smooth draw functions +* +******************************************************************************/ +// aline draw an aliased line on the bitmap +pub +fn (mut bmp BitMap) aline(in_x0 int, in_y0 int, in_x1 int, in_y1 int, c u32) { + //mut c1 := c + mut x0 := f32(in_x0) + mut x1 := f32(in_x1) + mut y0 := f32(in_y0) + mut y1 := f32(in_y1) + mut tmp := f32(0) + + mut dx := x1 - x0 + mut dy := y1 - y0 + + dist := f32(0.4) + + if fabs(dx) > fabs(dy) { + if x1 < x0 { + tmp = x0 + x0 = x1 + x1 = tmp + + tmp = y0 + y0 = y1 + y1 = tmp + } + dx = x1 - x0 + dy = y1 - y0 + + x0 += 0.5 + y0 += 0.5 + + m := dy / dx + mut x := x0 + for x <= x1 + 0.5 { + y := m * (x - x0) + y0 + e := 1-fabs(y-0.5-int(y)) + bmp.plot(int(x), int(y), color_multiply_alpha(c, e*0.75)) + + ys1 := y + dist + if int(ys1) != int(y){ + v1 := fabs(ys1 - y) / dist * (1 - e) + bmp.plot(int(x), int(ys1), color_multiply_alpha(c, v1)) + } + + ys2 := y - dist + if int(ys2) != int(y) { + v2 := fabs(y - ys2) / dist * (1 - e) + bmp.plot(int(x), int(ys2), color_multiply_alpha(c, v2)) + } + + x += 1.0 + } + + } else { + if y1 < y0 { + tmp = x0 + x0 = x1 + x1 = tmp + + tmp = y0 + y0 = y1 + y1 = tmp + } + dx = x1 - x0 + dy = y1 - y0 + + x0 += 0.5 + y0 += 0.5 + + n := dx / dy + mut y := y0 + for y <= y1 + 0.5 { + x := n * (y - y0) + x0 + e := f32(1 - fabs(x - 0.5 - int(x))) + bmp.plot(int(x), int(y), color_multiply_alpha(c, f32(e*0.75))) + + xs1 := x + dist + if int(xs1) != int(x) { + v1 := fabs(xs1 - x) / dist * (1 - e) + bmp.plot(int(xs1), int(y), color_multiply_alpha(c, f32(v1))) + } + + xs2 := x - dist + if int(xs2) != int(x) { + v2 := fabs(x - xs1) / dist * (1 - e) + bmp.plot(int(xs2), int(y), color_multiply_alpha(c, f32(v2))) + } + y += 1.0 + } + } +} + +/****************************************************************************** +* +* draw functions +* +******************************************************************************/ +pub +fn (mut bmp BitMap) line(in_x0 int, in_y0 int, in_x1 int, in_y1 int, c u32) { + + // outline with aliased borders + if bmp.style == .outline_aliased { + bmp.aline(in_x0, in_y0, in_x1, in_y1, c) + return + } + // filled with aliased borders + else if bmp.style == .filled { + bmp.aline(in_x0, in_y0, in_x1, in_y1, c) + bmp.fline(in_x0, in_y0, in_x1, in_y1, c) + return + } + // only the filler is drawn + else if bmp.style == .raw { + bmp.fline(in_x0, in_y0, in_x1, in_y1, c) + return + } + // if we are here we are drawing an outlined border + + x0 := int(in_x0) + x1 := int(in_x1) + y0 := int(in_y0) + y1 := int(in_y1) + //dprintln("line[$x0,$y0,$x1,$y1]") + + mut x := x0 + mut y := y0 + + dx := abs(x1 - x0) + sx := if x0 < x1 { 1 } else { -1 } + dy := -abs(y1 - y0) + sy := if y0 < y1 { 1 } else { -1 } + + // verical line + if dx == 0 { + if y0 < y1 { + for yt in y0..y1+1 { + bmp.plot(x0, yt, c) + } + return + } + for yt in y1..y0+1 { + bmp.plot(x0, yt, c) + } + return + // horizontal line + } else if dy == 0{ + if x0 < x1 { + for xt in x0..x1+1 { + bmp.plot(xt, y0, c) + } + return + } + for xt in x1..x0+1 { + bmp.plot(xt, y0, c) + } + return + } + + mut err := dx + dy // error value e_xy + for { + //bmp.plot(x, y, u32(0xFF00)) + bmp.plot(x, y, c) + + //dprintln("$x $y [$x0,$y0,$x1,$y1]") + if x == x1 && y == y1 { + break + } + e2 := 2 * err + if e2 >= dy { // e_xy+e_x > 0 + err += dy + x += sx + } + if e2 <= dx { // e_xy+e_y < 0 + err += dx + y += sy + } + } + +} + + +pub +fn (mut bmp BitMap) box(in_x0 int, in_y0 int, in_x1 int, in_y1 int, c u32) { + bmp.line(in_x0, in_y0, in_x1, in_y0, c) + bmp.line(in_x1, in_y0, in_x1, in_y1, c) + bmp.line(in_x0, in_y1, in_x1, in_y1, c) + bmp.line(in_x0, in_y0, in_x0, in_y1, c) +} + +pub +fn (mut bmp BitMap) quadratic(in_x0 int, in_y0 int, in_x1 int, in_y1 int, in_cx int, in_cy int, c u32) { + /* + x0 := int(in_x0 * bmp.scale) + x1 := int(in_x1 * bmp.scale) + y0 := int(in_y0 * bmp.scale) + y1 := int(in_y1 * bmp.scale) + cx := int(in_cx * bmp.scale) + cy := int(in_cy * bmp.scale) + */ + x0 := int(in_x0) + x1 := int(in_x1) + y0 := int(in_y0) + y1 := int(in_y1) + cx := int(in_cx) + cy := int(in_cy) + + mut division := f64(1.0) + dx := abs(x0 - x1) + dy := abs(y0 - y1) + + // if few pixel draw a simple line + //if dx == 0 && dy == 0 { + if dx <= 2 || dy <= 2 { + //bmp.plot(x0, y0, c) + bmp.line(x0,y0,x1,y1, c) + return + } + + division = 1.0/(f64( if dx>dy {dx} else {dy} )) + + //division = 0.1 // 10 division + //division = 0.25 // 4 division + + //dprintln("div: $division") + + /* + ----- Bezier quadratic form ----- + t = 0.5; // given example value, half length of the curve + x = (1 - t) * (1 - t) * p[0].x + 2 * (1 - t) * t * p[1].x + t * t * p[2].x; + y = (1 - t) * (1 - t) * p[0].y + 2 * (1 - t) * t * p[1].y + t * t * p[2].y; + --------------------------------- + */ + + mut x_old := x0 + mut y_old := y0 + mut t := 0.0 + + for t <= (1.0 + division/2.0){ + s := 1.0 - t + x := s * s * x0 + 2.0 * s * t * cx + t * t * x1 + y := s * s * y0 + 2.0 * s * t * cy + t * t * y1 + xi := int(x + 0.5) + yi := int(y + 0.5) + //bmp.plot(xi, yi, c) + bmp.line(x_old, y_old, xi, yi, c) + x_old = xi + y_old = yi + t += division + } +} + +/****************************************************************************** +* +* TTF Query functions +* +******************************************************************************/ +pub +fn (mut bmp BitMap) get_chars_bbox(in_string string) []int { + mut res := []int{} + mut w := 0 + + mut space_cw, _ := bmp.tf.get_horizontal_metrics(u16(` `)) + div_space_cw := int((f32(space_cw) * bmp.space_mult) * bmp.scale) + space_cw = int(space_cw * bmp.scale) + + bmp.tf.reset_kern() + + mut i := 0 + for i < in_string.len { + mut char := u16(in_string[i]) + + // draw the space + if int(char) == 32 { + w += int(space_cw * bmp.space_cw) + i++ + continue + } + + // manage unicode chars like latin greek etc + c_len := ((0xe5000000>>((char>>3) & 0x1e)) & 3) + 1 + if c_len > 1 { + tmp_char := utf8.get_uchar(in_string,i) + //dprintln("tmp_char: ${tmp_char.hex()}") + char = u16(tmp_char) + } + + c_index := bmp.tf.map_code(int(char)) + ax , ay := bmp.tf.next_kern(c_index) + //dprintln("char_index: $c_index ax: $ax ay: $ay") + + //cw, lsb := bmp.tf.get_horizontal_metrics(u16(char)) + //dprintln("metrics: [${u16(char):c}] cw:$cw lsb:$lsb") + + //----- Calc Glyph transformations ----- + mut x0 := w + int(ax * bmp.scale) + mut y0 := 0 + int(ay * bmp.scale) + + p := Point{x0,y0,false} + x1 , y1 := bmp.trf_txt(p) + // init ch_matrix + bmp.ch_matrix[0] = bmp.tr_matrix[0] * bmp.scale * bmp.scale_x + bmp.ch_matrix[1] = bmp.tr_matrix[1] * bmp.scale * bmp.scale_x + bmp.ch_matrix[3] = bmp.tr_matrix[3] * -bmp.scale * bmp.scale_y + bmp.ch_matrix[4] = bmp.tr_matrix[4] * -bmp.scale * bmp.scale_y + bmp.ch_matrix[6] = int(x1) + bmp.ch_matrix[7] = int(y1) + + //x_min, x_max, y_min, y_max := bmp.tf.read_glyph_dim(c_index) + x_min, x_max, _, _ := bmp.tf.read_glyph_dim(c_index) + //----------------- + + width := int( (abs(x_max + x_min) + ax) * bmp.scale) + //width := int((cw+ax) * bmp.scale) + w += width + div_space_cw + h := int(abs(int(bmp.tf.y_max - bmp.tf.y_min)) * bmp.scale) + res << w + res << h + + i+= c_len + } + return res +} + +pub +fn (mut bmp BitMap) get_bbox(in_string string) (int, int){ + mut w := 0 + + mut space_cw, _ := bmp.tf.get_horizontal_metrics(u16(` `)) + div_space_cw := int((f32(space_cw) * bmp.space_mult) * bmp.scale) + space_cw = int(space_cw * bmp.scale) + + bmp.tf.reset_kern() + + mut i := 0 + for i < in_string.len { + mut char := u16(in_string[i]) + + // draw the space + if int(char) == 32 { + w += int(space_cw * bmp.space_cw) + i++ + continue + } + + // manage unicode chars like latin greek etc + c_len := ((0xe5000000>>((char>>3) & 0x1e)) & 3) + 1 + if c_len > 1 { + tmp_char := utf8.get_uchar(in_string,i) + //dprintln("tmp_char: ${tmp_char.hex()}") + char = u16(tmp_char) + } + + c_index := bmp.tf.map_code(int(char)) + ax , ay := bmp.tf.next_kern(c_index) + //dprintln("char_index: $c_index ax: $ax ay: $ay") + + //cw, lsb := bmp.tf.get_horizontal_metrics(u16(char)) + //dprintln("metrics: [${u16(char):c}] cw:$cw lsb:$lsb") + + //----- Calc Glyph transformations ----- + mut x0 := w + int(ax * bmp.scale) + mut y0 := 0 + int(ay * bmp.scale) + + p := Point{x0,y0,false} + x1 , y1 := bmp.trf_txt(p) + // init ch_matrix + bmp.ch_matrix[0] = bmp.tr_matrix[0] * bmp.scale * bmp.scale_x + bmp.ch_matrix[1] = bmp.tr_matrix[1] * bmp.scale * bmp.scale_x + bmp.ch_matrix[3] = bmp.tr_matrix[3] * -bmp.scale * bmp.scale_y + bmp.ch_matrix[4] = bmp.tr_matrix[4] * -bmp.scale * bmp.scale_y + bmp.ch_matrix[6] = int(x1) + bmp.ch_matrix[7] = int(y1) + + x_min, x_max, _, _ := bmp.tf.read_glyph_dim(c_index) + //x_min := 1 + //x_max := 2 + //----------------- + + width := int( (abs(x_max + x_min) + ax) * bmp.scale) + //width := int((cw+ax) * bmp.scale) + w += width + div_space_cw + + i+= c_len + } + + //dprintln("y_min: $bmp.tf.y_min y_max: $bmp.tf.y_max res: ${int((bmp.tf.y_max - bmp.tf.y_min)*buf.scale)} width: ${int( (cw) * buf.scale)}") + //buf.box(0,y_base - int((bmp.tf.y_min)*buf.scale), int( (x_max) * buf.scale), y_base-int((bmp.tf.y_max)*buf.scale), u32(0xFF00_0000) ) + return w , int(abs(int(bmp.tf.y_max - bmp.tf.y_min)) * bmp.scale) +} + +/****************************************************************************** +* +* TTF draw glyph +* +******************************************************************************/ +pub +fn (mut bmp BitMap) draw_text(in_string string) (int, int){ + mut w := 0 + + mut space_cw, _ := bmp.tf.get_horizontal_metrics(u16(` `)) + div_space_cw := int((f32(space_cw) * bmp.space_mult) * bmp.scale) + space_cw = int(space_cw * bmp.scale) + + bmp.tf.reset_kern() + + mut i := 0 + for i < in_string.len { + mut char := u16(in_string[i]) + + // draw the space + if int(char) == 32 { + w += int(space_cw * bmp.space_cw) + i++ + continue + } + + // manage unicode chars like latin greek etc + c_len := ((0xe5000000>>((char>>3) & 0x1e)) & 3) + 1 + if c_len > 1 { + tmp_char := utf8.get_uchar(in_string,i) + //dprintln("tmp_char: ${tmp_char.hex()}") + char = u16(tmp_char) + } + + c_index := bmp.tf.map_code(int(char)) + ax , ay := bmp.tf.next_kern(c_index) + //dprintln("char_index: $c_index ax: $ax ay: $ay") + + cw, _ := bmp.tf.get_horizontal_metrics(u16(char)) + //cw, lsb := bmp.tf.get_horizontal_metrics(u16(char)) + //dprintln("metrics: [${u16(char):c}] cw:$cw lsb:$lsb") + + //----- Draw_Glyph transformations ----- + mut x0 := w + int(ax * bmp.scale) + mut y0 := 0 + int(ay * bmp.scale) + + p := Point{x0,y0,false} + x1 , y1 := bmp.trf_txt(p) + // init ch_matrix + bmp.ch_matrix[0] = bmp.tr_matrix[0] * bmp.scale * bmp.scale_x + bmp.ch_matrix[1] = bmp.tr_matrix[1] * bmp.scale * bmp.scale_x + bmp.ch_matrix[3] = bmp.tr_matrix[3] * -bmp.scale * bmp.scale_y + bmp.ch_matrix[4] = bmp.tr_matrix[4] * -bmp.scale * bmp.scale_y + bmp.ch_matrix[6] = int(x1) + bmp.ch_matrix[7] = int(y1) + + x_min, x_max := bmp.draw_glyph(c_index) + // x_min := 1 + // x_max := 2 + //----------------- + + mut width := int( (abs(x_max + x_min) + ax) * bmp.scale) + if bmp.use_font_metrics { + width = int((cw+ax) * bmp.scale) + } + w += width + div_space_cw + + i+= c_len + } + + //dprintln("y_min: $bmp.tf.y_min y_max: $bmp.tf.y_max res: ${int((bmp.tf.y_max - bmp.tf.y_min)*buf.scale)} width: ${int( (cw) * buf.scale)}") + //buf.box(0,y_base - int((bmp.tf.y_min)*buf.scale), int( (x_max) * buf.scale), y_base-int((bmp.tf.y_max)*buf.scale), u32(0xFF00_0000) ) + return w , int(abs(int(bmp.tf.y_max - bmp.tf.y_min)) * bmp.scale) +} + +pub +fn (mut bmp BitMap) draw_glyph(index u16) (int, int){ + glyph := bmp.tf.read_glyph(index) + + if !glyph.valid_glyph { + return 0, 0 + } + + if bmp.style == .filled || bmp.style == .raw { + bmp.clear_filler() + } + + mut s := 0 // status + mut c := 0 // contours count + mut contour_start := 0 + mut x0 := 0 + mut y0 := 0 + color := bmp.color //u32(0xFFFF_FF00) // RGBA white + //color1 := u32(0xFF00_0000) // RGBA red + //color2 := u32(0x00FF_0000) // RGBA green + + mut sp_x := 0 + mut sp_y := 0 + mut point := Point{} + + for count, point_raw in glyph.points { + //dprintln("count: $count, state: $s pl:$glyph.points.len") + point.x = point_raw.x + point.y = point_raw.y + + point.x , point.y = bmp.trf_ch(point) + point.on_curve = point_raw.on_curve + + if s == 0 { + x0 = point.x + y0 = point.y + sp_x = x0 + sp_y = y0 + s = 1 // next state + continue + } else if s == 1 { + if point.on_curve { + bmp.line(x0, y0, point.x, point.y, color) + //bmp.aline(x0, y0, point.x, point.y, u32(0xFFFF0000)) + x0 = point.x + y0 = point.y + } else { + s = 2 + } + + } else { + //dprintln("s==2") + mut prev := glyph.points[count - 1] + prev.x, prev.y = bmp.trf_ch(prev) + if point.on_curve { + //dprintln("HERE1") + // ctx.quadraticCurveTo(prev.x + x, prev.y + y,point.x + x, point.y + y); + //bmp.line(x0, y0, point.x + in_x, point.y + in_y, color1) + //bmp.quadratic(x0, y0, point.x + in_x, point.y + in_y, prev.x + in_x, prev.y + in_y, u32(0xa0a00000)) + bmp.quadratic(x0, y0, point.x, point.y, prev.x, prev.y, color) + x0 = point.x + y0 = point.y + s = 1 + } else { + //dprintln("HERE2") + // ctx.quadraticCurveTo(prev.x + x, prev.y + y, + // (prev.x + point.x) / 2 + x, + // (prev.y + point.y) / 2 + y); + + //bmp.line(x0, y0, (prev.x + point.x)/2, (prev.y + point.y)/2, color2) + //bmp.quadratic(x0, y0, (prev.x + point.x)/2, (prev.y + point.y)/2, prev.x, prev.y, color2) + bmp.quadratic(x0, y0, (prev.x + point.x)/2, (prev.y + point.y)/2, prev.x, prev.y, color) + x0 = (prev.x + point.x)/2 + y0 = (prev.y + point.y)/2 + } + } + + if count == glyph.contour_ends[c] { + //dprintln("count == glyph.contour_ends[count]") + if s == 2 { // final point was off-curve. connect to start + + mut start_point := glyph.points[contour_start] + start_point.x, start_point.y = bmp.trf_ch(start_point) + if point.on_curve { + //ctx.quadraticCurveTo(prev.x + x, prev.y + y, + // point.x + x, point.y + y); + //bmp.line(x0, y0, start_point.x + in_x, start_point.y + in_y, u32(0x00FF0000)) + + bmp.quadratic(x0, y0, start_point.x, start_point.y , + // start_point.x + in_x, start_point.y + in_y, u32(0xFF00FF00)) + start_point.x, start_point.y, color) + } else { + //ctx.quadraticCurveTo(prev.x + x, prev.y + y, + // (prev.x + point.x) / 2 + x, + // (prev.y + point.y) / 2 + y); + + //bmp.line(x0, y0, start_point.x, start_point.y, u32(0x00FF0000) + bmp.quadratic(x0, y0, start_point.x, start_point.y, + (point.x + start_point.x)/2, + (point.y + start_point.y)/2, + //u32(0xFF000000)) + color) + } + }else{ + // last point not in a curve + //bmp.line(point.x, point.y, sp_x, sp_y, u32(0x00FF0000)) + bmp.line(point.x, point.y, sp_x, sp_y, color) + } + contour_start = count + 1 + s = 0 + c++ + } + } + + if bmp.style == .filled || bmp.style == .raw { + bmp.exec_filler() + } + x_min := glyph.x_min + x_max := glyph.x_max + return x_min, x_max + + //return glyph.x_min, glyph.x_max +} diff --git a/vlib/x/ttf/render_sokol_cpu.v b/vlib/x/ttf/render_sokol_cpu.v new file mode 100644 index 0000000000..9695459b01 --- /dev/null +++ b/vlib/x/ttf/render_sokol_cpu.v @@ -0,0 +1,234 @@ +module ttf +/********************************************************************** +* +* BMP render module utility functions +* +* Copyright (c) 2021 Dario Deledda. All rights reserved. +* Use of this source code is governed by an MIT license +* that can be found in the LICENSE file. +* +* Note: +* +* TODO: +**********************************************************************/ +import math +import gg +import sokol.sgl + +pub +struct TTF_render_Sokol { +pub mut: + bmp &BitMap // Base bitmap render + + // rendering fields + sg_img C.sg_image // sokol image + scale_reduct f32 = 2.0 // scale of the cpu texture for filtering + device_dpi int = 72 // device DPI +} + +/****************************************************************************** +* +* Render functions +* +******************************************************************************/ +fn (mut tf_skl TTF_render_Sokol) format_texture(){ + r := byte(tf_skl.bmp.color >> 24) + g := byte((tf_skl.bmp.color >> 16) & 0xFF) + b := byte((tf_skl.bmp.color >> 8 ) & 0xFF) + a := byte(tf_skl.bmp.color & 0xFF) + + b_r := byte(tf_skl.bmp.bg_color >> 24) + b_g := byte((tf_skl.bmp.bg_color >> 16) & 0xFF) + b_b := byte((tf_skl.bmp.bg_color >> 8 ) & 0xFF) + b_a := byte(tf_skl.bmp.bg_color & 0xFF) + + // trasform buffer in a texture + x := byteptr(tf_skl.bmp.buf) + unsafe{ + mut i := 0 + for i 0 { + x[i+0] = r + x[i+1] = g + x[i+2] = b + // alpha + x[i+3] = byte((a * data) >> 8) + } else { + x[i+0] = b_r + x[i+1] = b_g + x[i+2] = b_b + x[i+3] = b_a + } + i += 4 + } + } +} + +pub +fn (mut tf_skl TTF_render_Sokol) create_text(in_txt string, in_font_size f32){ + scale_reduct := tf_skl.scale_reduct + device_dpi := tf_skl.device_dpi + font_size := in_font_size //* scale_reduct + + // Formula: (font_size * device dpi) / (72dpi * em_unit) + //scale := ((1.0 * devide_dpi )/ f32(72 * tf_skl.bmp.tf.units_per_em))* font_size + scale := f32(font_size * device_dpi) / f32(72 * tf_skl.bmp.tf.units_per_em) + //dprintln("Scale: $scale") + + tf_skl.bmp.scale = scale * scale_reduct + w, h := tf_skl.bmp.get_bbox(in_txt) + tf_skl.bmp.width = int(w) + tf_skl.bmp.height = int((h+8)) + sz := tf_skl.bmp.width * tf_skl.bmp.height * tf_skl.bmp.bp + + // RAM buffer + if sz > tf_skl.bmp.buf_size { + if sz > 0 { + free(tf_skl.bmp.buf) + } + dprintln("create_text Alloc: $sz bytes") + tf_skl.bmp.buf = malloc(sz) + tf_skl.bmp.buf_size = sz + } + + tf_skl.bmp.init_filler() + + // draw the text + mut y_base := int((tf_skl.bmp.tf.y_max - tf_skl.bmp.tf.y_min) * tf_skl.bmp.scale) + tf_skl.bmp.set_pos(0,y_base) + tf_skl.bmp.clear() + tf_skl.bmp.draw_text(in_txt) + tf_skl.format_texture() +} + +pub +fn (mut tf_skl TTF_render_Sokol) create_text_block(in_txt string, in_w int, in_h int, in_font_size f32){ + scale_reduct := tf_skl.scale_reduct + device_dpi := tf_skl.device_dpi + font_size := in_font_size //* scale_reduct + // Formula: (font_size * device dpi) / (72dpi * em_unit) + //scale := ((1.0 * devide_dpi )/ f32(72 * tf_skl.bmp.tf.units_per_em))* font_size + scale := f32(font_size * device_dpi) / f32(72 * tf_skl.bmp.tf.units_per_em) + //dprintln("Scale: $scale") + + tf_skl.bmp.scale = scale * scale_reduct + w := in_w + h := in_h + tf_skl.bmp.width = int(w * scale_reduct + 0.5) + tf_skl.bmp.height = int((h+2) * scale_reduct + 0.5) + sz := tf_skl.bmp.width * tf_skl.bmp.height * tf_skl.bmp.bp + + //if true { return } + + // RAM buffer + if sz > tf_skl.bmp.buf_size { + if sz > 0 { + free(tf_skl.bmp.buf) + } + dprintln("Alloc: $sz bytes") + tf_skl.bmp.buf = malloc(sz) + tf_skl.bmp.buf_size = sz + } + + tf_skl.bmp.init_filler() + + // draw the text + mut y_base := int((tf_skl.bmp.tf.y_max - tf_skl.bmp.tf.y_min) * tf_skl.bmp.scale) + tf_skl.bmp.set_pos(0,y_base) + tf_skl.bmp.clear() + + tf_skl.bmp.draw_text_block(in_txt, {x: 0, y:0, w:w, h:h}) + tf_skl.format_texture() +} +/****************************************************************************** +* +* Sokol Render functions +* +******************************************************************************/ +pub +fn (mut tf_skl TTF_render_Sokol) create_texture(){ + w := tf_skl.bmp.width + h := tf_skl.bmp.height + sz := tf_skl.bmp.width * tf_skl.bmp.height * tf_skl.bmp.bp + mut img_desc := C.sg_image_desc{ + width: w + height: h + num_mipmaps: 0 + min_filter: .linear + mag_filter: .linear + //usage: .dynamic + wrap_u: .clamp_to_edge + wrap_v: .clamp_to_edge + label: &byte(0) + d3d11_texture: 0 + } + // comment for dynamic + img_desc.content.subimage[0][0] = C.sg_subimage_content{ + ptr: tf_skl.bmp.buf + size: sz + } + + simg := C.sg_make_image(&img_desc) + //free(tf_skl.bmp.buf) // DONT FREE IF Dynamic + tf_skl.sg_img = simg +} + +pub +fn (tf_skl TTF_render_Sokol) destroy_texture(){ + C.sg_destroy_image(tf_skl.sg_img) +} + +// Use only if usage: .dynamic +pub +fn (mut tf_skl TTF_render_Sokol) update_text_texture(){ + sz := tf_skl.bmp.width * tf_skl.bmp.height * tf_skl.bmp.bp + mut tmp_sbc := C.sg_image_content{} + tmp_sbc.subimage[0][0] = C.sg_subimage_content { + ptr: tf_skl.bmp.buf + size: sz + } + C.sg_update_image(tf_skl.sg_img, &tmp_sbc) +} + +pub +fn (tf_skl TTF_render_Sokol) draw_text_bmp(ctx &gg.Context, x f32, y f32) { + //width := tf_skl.bmp.width >> 1 + //height := tf_skl.bmp.height >> 1 + sgl.push_matrix() + + width := tf_skl.bmp.width / (tf_skl.scale_reduct) + height := tf_skl.bmp.height / (tf_skl.scale_reduct) + + u0 := f32(0.0) + v0 := f32(0.0) + u1 := f32(1.0) + v1 := f32(1.0) + x0 := f32(0) + y0 := f32(0) + x1 := f32(width) * ctx.scale + y1 := f32(height) * ctx.scale + + ca := f32(math.cos(tf_skl.bmp.angle)) + sa := f32(math.sin(tf_skl.bmp.angle)) + m := [ + f32(ca),-sa,0,0, + sa,ca,0,0, + 0,0,1,0, + x,y,0,1 + ] + sgl.mult_matrix(m) + // + sgl.load_pipeline(ctx.timage_pip) + sgl.enable_texture() + sgl.texture(tf_skl.sg_img) + sgl.begin_quads() + sgl.c4b(255, 255, 255, 255) + sgl.v2f_t2f(x0, y0, u0, v0) + sgl.v2f_t2f(x1, y0, u1, v0) + sgl.v2f_t2f(x1, y1, u1, v1) + sgl.v2f_t2f(x0, y1, u0, v1) + sgl.end() + sgl.disable_texture() + sgl.pop_matrix() +} diff --git a/vlib/x/ttf/text_block.v b/vlib/x/ttf/text_block.v new file mode 100644 index 0000000000..7af46d80e4 --- /dev/null +++ b/vlib/x/ttf/text_block.v @@ -0,0 +1,122 @@ +module ttf +/********************************************************************** +* +* BMP render module utility functions +* +* Copyright (c) 2021 Dario Deledda. All rights reserved. +* Use of this source code is governed by an MIT license +* that can be found in the LICENSE file. +* +* Note: +* +* TODO: +**********************************************************************/ +pub +struct Text_block { + x int + y int + w int // width of the text block + h int // heigth of the text block + cut_lines bool = true +} + + +fn (mut dev BitMap) get_justify_space_cw(txt string, w int, block_w int, space_cw int) f32 { + num_spaces := txt.count(" ") + if num_spaces < 1 { + return 0 + } + delta := block_w - w + //println("num spc: $num_spaces") + //println("delta: ${txt} w:$w bw:$block_w space_cw:$space_cw") + res := f32(delta)/f32(num_spaces)/f32(space_cw) + //println("res: $res") + return res +} + +// write out a text +pub +fn (mut bmp BitMap) draw_text_block(text string, block Text_block) { + mut x := block.x + mut y := block.y + mut y_base := int((bmp.tf.y_max - bmp.tf.y_min) * bmp.scale) + + //bmp.box(x, y, x + block.w, y + block.h, u32(0xFF00_0000)) + + // spaces data + mut space_cw, _ := bmp.tf.get_horizontal_metrics(u16(` `)) + space_cw = int(space_cw * bmp.scale) + + old_space_cw := bmp.space_cw + + mut offset_flag := f32(0) // default .left align + if bmp.align == .right { + offset_flag = 1 + } else if bmp.align == .center { + offset_flag = 0.5 + } + + for txt in text.split_into_lines() { + bmp.space_cw = old_space_cw + mut w,mut h := bmp.get_bbox(txt) + if w <= block.w || block.cut_lines == false { + //println("Solid block!") + left_offset := int((block.w - w) * offset_flag) + if bmp.justify && (f32(w) / f32(block.w)) >= bmp.justify_fill_ratio { + bmp.space_cw = old_space_cw + bmp.get_justify_space_cw(txt, w, block.w, space_cw) + } + bmp.set_pos(x + left_offset ,y + y_base) + bmp.draw_text(txt) + //---- DEBUG ---- + //mut txt_w , mut txt_h := bmp.draw_text(txt) + //bmp.box(x + left_offset,y+y_base - int((bmp.tf.y_min)*bmp.scale), x + txt_w + left_offset, y + y_base - int((bmp.tf.y_max) * bmp.scale), u32(0x00ff_0000) ) + //--------------- + y += y_base + } else { + //println("to cut: ${txt}") + mut txt1 := txt.split(" ") + mut c:= txt1.len + //mut done := false + for c > 0 { + tmp_str := txt1[0..c].join(' ') + //println("tmp_str: ${tmp_str}") + if tmp_str.len < 1 { + break + } + + bmp.space_cw = old_space_cw + w,h = bmp.get_bbox(tmp_str) + if w <= block.w { + mut left_offset := int((block.w - w) * offset_flag) + if bmp.justify && (f32(w) / f32(block.w)) >= bmp.justify_fill_ratio { + //println("cut phase!") + bmp.space_cw = 0.0 + w,h = bmp.get_bbox(tmp_str) + left_offset = int((block.w - w) * offset_flag) + bmp.space_cw = bmp.get_justify_space_cw(tmp_str, w, block.w, space_cw) + } else { + bmp.space_cw = old_space_cw + } + bmp.set_pos(x + left_offset, y + y_base) + bmp.draw_text(tmp_str) + //---- DEBUG ---- + //txt_w , txt_h := bmp.draw_text(tmp_str) + //println("printing [${x},${y}] => '${tmp_str}' space_cw: $bmp.space_cw") + //bmp.box(x + left_offset,y + y_base - int((bmp.tf.y_min)*bmp.scale), x + txt_w + left_offset, y + y_base - int((bmp.tf.y_max) * bmp.scale), u32(0x00ff_0000) ) + //--------------- + y += y_base + txt1 = txt1[c..] + c= txt1.len + //---- DEBUG ---- + //txt2 := txt1.join(' ') + //println("new string: ${txt2} len: ${c}") + //--------------- + } else { + c-- + } + } + } + } + + bmp.space_cw = old_space_cw +} \ No newline at end of file diff --git a/vlib/x/ttf/ttf.v b/vlib/x/ttf/ttf.v new file mode 100644 index 0000000000..12902abf32 --- /dev/null +++ b/vlib/x/ttf/ttf.v @@ -0,0 +1,1115 @@ +module ttf +/********************************************************************** +* +* TrueTypeFont reader V implementation +* +* Copyright (c) 2021 Dario Deledda. All rights reserved. +* Use of this source code is governed by an MIT license +* that can be found in the LICENSE file. +* +* Note: +* - inspired by: http://stevehanov.ca/blog/?id=143 +* +* TODO: +* - check for unicode > 0xFFFF if supported +* - evaluate use a buffer for the points in the glyph +**********************************************************************/ +import strings + + +/****************************************************************************** +* +* CMAP structs +* +******************************************************************************/ +struct Segment { +mut: + id_range_offset u32 + start_code u16 + end_code u16 + id_delta u16 +} + +struct TrueTypeCmap { +mut: + format int + cache []int = []int{ len: 65536, init: -1 } // for now we allocate 2^16 charcode + segments []Segment + arr []int +} + +/****************************************************************************** +* +* TTF_File structs +* +******************************************************************************/ +pub +struct TTF_File{ +pub mut: + buf []byte + pos u32 + + length u16 + + scalar_type u32 + search_range u16 + entry_selector u16 + range_shift u16 + + tables map[string]Offset_Table + + version f32 + font_revision f32 + checksum_adjustment u32 + magic_number u32 + flags u16 + units_per_em u16 + created u64 + modified u64 + x_min f32 + y_min f32 + x_max f32 + y_max f32 + mac_style u16 + lowest_rec_ppem u16 + font_direction_hint i16 + index_to_loc_format i16 + glyph_data_format i16 + + font_family string + font_sub_family string + full_name string + postscript_name string + + cmaps []TrueTypeCmap + + ascent i16 + descent i16 + line_gap i16 + advance_width_max u16 + min_left_side_bearing i16 + min_right_side_bearing i16 + x_max_extent i16 + caret_slope_rise i16 + caret_slope_run i16 + caret_offset i16 + metric_data_format i16 + num_of_long_hor_metrics u16 + + kern []Kern0Table + + // cache + glyph_cache map[int]Glyph +} + +pub +fn (mut tf TTF_File) init() { + tf.read_offset_tables() + tf.read_head_table() + //dprintln(tf.get_info_string()) + tf.read_name_table() + tf.read_cmap_table() + tf.read_hhea_table() + tf.read_kern_table() + tf.length = tf.glyph_count() + dprintln("Number of symbols: $tf.length") + dprintln("*****************************") +} +/****************************************************************************** +* +* TTF_File Glyph Structs +* +******************************************************************************/ + +pub +struct Point { +pub mut: + x int + y int + on_curve bool +} + +struct Gylph_Component { +mut: + points []Point +} + +// type of glyph +const( + g_type_simple = u16(1) // simple type + g_type_complex = u16(2) // compound type +) + +pub +struct Glyph { +pub mut: + g_type u16 = g_type_simple + contour_ends []u16 + number_of_contours i16 + points []Point + x_min i16 + x_max i16 + y_min i16 + y_max i16 + valid_glyph bool + components []Component +} + + +/****************************************************************************** +* +* TTF_File metrics and glyph +* +******************************************************************************/ +pub +fn (mut tf TTF_File) get_horizontal_metrics(glyph_index u16) (int, int) { + assert"hmtx" in tf.tables + old_pos := tf.pos + mut offset := tf.tables["hmtx"].offset + + mut advance_width := 0 + mut left_side_bearing := 0 + if glyph_index < tf.num_of_long_hor_metrics { + offset += glyph_index * 4 + tf.pos = offset + advance_width = tf.get_u16() + left_side_bearing = tf.get_i16() + //dprintln("Found h_metric aw: $advance_width lsb: $left_side_bearing") + } else { + // read the last entry of the hMetrics array + tf.pos = offset + (tf.num_of_long_hor_metrics - 1) * 4 + advance_width = tf.get_u16() + tf.pos = offset + tf.num_of_long_hor_metrics * 4 + 2 * (glyph_index - tf.num_of_long_hor_metrics) + left_side_bearing = tf.get_fword() + } + tf.pos = old_pos + return advance_width, left_side_bearing +} + +fn (mut tf TTF_File) get_glyph_offset(index u32) u32{ + // check if needed tables exists + assert "loca" in tf.tables + assert "glyf" in tf.tables + mut old_pos := tf.pos + + table := tf.tables["loca"] + mut offset := u32(0) + mut next := u32(0) + if tf.index_to_loc_format == 1 { + tf.pos = table.offset + (index << 2) + offset = tf.get_u32() + next = tf.get_u32() + } else { + tf.pos = table.offset + (index << 1) + offset = tf.get_u16() << 1 + next = tf.get_u16() << 1 + } + + if offset == next { + // indicates glyph has no outline( eg space) + return 0 + } + + //dprintln("Offset for glyph index $index is $offset") + tf.pos = old_pos + return offset + tf.tables['glyf'].offset +} + +fn (mut tf TTF_File) glyph_count() u16{ + assert "maxp" in tf.tables + old_pos := tf.pos + tf.pos = tf.tables["maxp"].offset + 4 + count := tf.get_u16() + tf.pos = old_pos + return count +} + +pub +fn (mut tf TTF_File) read_glyph_dim(index u16) (int, int, int, int) { + offset := tf.get_glyph_offset(index) + //dprintln("offset: $offset") + if offset == 0 || offset >= tf.tables["glyf"].offset + tf.tables["glyf"].length { + dprintln("No glyph found!") + return 0, 0, 0, 0 + } + + assert offset >= tf.tables["glyf"].offset + assert offset < tf.tables["glyf"].offset + tf.tables["glyf"].length + + tf.pos = offset + //dprintln("file seek read_glyph: $tf.pos") + + /*number_of_contours*/ _ := tf.get_i16() + x_min := tf.get_fword() + y_min := tf.get_fword() + x_max := tf.get_fword() + y_max := tf.get_fword() + + return x_min, x_max, y_min, y_max +} + +pub +fn (mut tf TTF_File) read_glyph(index u16) Glyph { + index_int := int(index) //index.str() + if index_int in tf.glyph_cache{ + //dprintln("Found glyp: ${index}") + return tf.glyph_cache[index_int] + } + //dprintln("Create glyp: ${index}") + + offset := tf.get_glyph_offset(index) + //dprintln("offset: $offset") + if offset == 0 || offset >= tf.tables["glyf"].offset + tf.tables["glyf"].length { + dprintln("No glyph found!") + return Glyph{} + } + + assert offset >= tf.tables["glyf"].offset + assert offset < tf.tables["glyf"].offset + tf.tables["glyf"].length + + tf.pos = offset + //dprintln("file seek read_glyph: $tf.pos") + + /* ---- BUG TO SOLVE ----- + --- Order of the data if printed in the main is shuffled!! Very Strange + mut tmp_glyph := Glyph{ + number_of_contours : tf.get_i16() + x_min : tf.get_fword() + y_min : tf.get_fword() + x_max : tf.get_fword() + y_max : tf.get_fword() + } + */ + + mut tmp_glyph := Glyph{} + tmp_glyph.number_of_contours = tf.get_i16() + tmp_glyph.x_min = tf.get_fword() + tmp_glyph.y_min = tf.get_fword() + tmp_glyph.x_max = tf.get_fword() + tmp_glyph.y_max = tf.get_fword() + + //dprintln("file seek after read_glyph: $tf.pos") + + assert tmp_glyph.number_of_contours >= -1 + + if tmp_glyph.number_of_contours == -1 { + //dprintln("read_compound_glyph") + tf.read_compound_glyph(mut tmp_glyph) + } else { + //dprintln("read_simple_glyph") + tf.read_simple_glyph(mut tmp_glyph) + } + + tf.glyph_cache[index_int] = tmp_glyph + return tmp_glyph +} + +const( + tfk_on_curve = 1 + tfk_x_is_byte = 2 + tfk_y_is_byte = 4 + tfk_repeat = 8 + tfk_x_delta = 16 + tfk_y_delta = 32 +) + +fn (mut tf TTF_File) read_simple_glyph(mut in_glyph Glyph){ + if in_glyph.number_of_contours == 0 { + return + } + + for _ in 0..in_glyph.number_of_contours { + in_glyph.contour_ends << tf.get_u16() + } + + // skip over intructions + tf.pos = tf.get_u16() + tf.pos + + mut num_points := 0 + for ce in in_glyph.contour_ends { + if ce > num_points { + num_points = ce + } + } + num_points++ + + mut i := 0 + mut flags := []byte{} + for i < num_points { + flag := tf.get_u8() + flags << flag + in_glyph.points << Point{ + x: 0 + y: 0 + on_curve: (flag & tfk_on_curve) > 0 + } + + if (flag & tfk_repeat) > 0 { + mut repeat_count := tf.get_u8() + assert repeat_count > 0 + i += repeat_count + for repeat_count > 0 { + flags << flag + in_glyph.points << Point{ + x: 0 + y: 0 + on_curve: (flag & tfk_on_curve) > 0 + } + repeat_count-- + } + } + i++ + } + + // read coords x + mut value := 0 + for i_x in 0..num_points { + flag_x := flags[i_x] + if (flag_x & tfk_x_is_byte) > 0 { + if (flag_x & tfk_x_delta) > 0 { + value += tf.get_u8() + } else { + value -= tf.get_u8() + } + } else if (~flag_x & tfk_x_delta) > 0 { + value += tf.get_i16() + } else { + // value is unchanged + } + //dprintln("$i_x x: $value") + in_glyph.points[i_x].x = value + } + + // read coords y + value = 0 + for i_y in 0..num_points { + flag_y := flags[i_y] + if (flag_y & tfk_y_is_byte) > 0 { + if (flag_y & tfk_y_delta) > 0 { + value += tf.get_u8() + } else { + value -= tf.get_u8() + } + } else if (~flag_y & tfk_y_delta) > 0 { + value += tf.get_i16() + } else { + // value is unchanged + } + //dprintln("$i_y y: $value") + in_glyph.points[i_y].y = value + } + + // ok we have a valid glyph + in_glyph.valid_glyph = true +} + +const( + tfkc_arg_1_and_2_are_words = 1 + tfkc_args_are_xy_values = 2 + tfkc_round_xy_to_grid = 4 + tfkc_we_have_a_scale = 8 + // reserved = 16 + tfkc_more_components = 32 + tfkc_we_have_an_x_and_y_scale = 64 + tfkc_we_have_a_two_by_two = 128 + tfkc_we_have_instructions = 256 + tfkc_use_my_metrics = 512 + tfkc_overlap_component = 1024 +) + +struct Component { +mut: + glyph_index u16 + dest_point_index i16 + src_point_index i16 + matrix []f32 = [f32(1.0), 0, 0, 1.0, 0, 0] +} + +fn (mut tf TTF_File) read_compound_glyph(mut in_glyph Glyph){ + in_glyph.g_type = g_type_complex + mut component := Component{} + mut flags := tfkc_more_components + for (flags & tfkc_more_components) > 0 { + mut arg1 := i16(0) + mut arg2 := i16(0) + + flags = tf.get_u16() + + component.glyph_index = tf.get_u16() + + if (flags & tfkc_arg_1_and_2_are_words) > 0 { + arg1 = tf.get_i16() + arg2 = tf.get_i16() + } else { + arg1 = tf.get_u8() + arg2 = tf.get_u8() + } + + if (flags & tfkc_args_are_xy_values) > 0 { + component.matrix[4] = arg1 + component.matrix[5] = arg2 + } else { + component.dest_point_index = arg1 + component.src_point_index = arg2 + } + + if (flags & tfkc_we_have_a_scale) > 0 { + component.matrix[0] = tf.get_2dot14() + component.matrix[3] = component.matrix[0] + } else if (flags & tfkc_we_have_an_x_and_y_scale) > 0 { + component.matrix[0] = tf.get_2dot14() + component.matrix[3] = tf.get_2dot14() + } else if (flags & tfkc_we_have_a_two_by_two) > 0 { + component.matrix[0] = tf.get_2dot14() + component.matrix[1] = tf.get_2dot14() + component.matrix[2] = tf.get_2dot14() + component.matrix[3] = tf.get_2dot14() + } + + //dprintln("Read component glyph index ${component.glyph_index}") + //dprintln("Transform: ${component.matrix}") + + old_pos := tf.pos + + simple_glyph := tf.read_glyph(component.glyph_index) + if simple_glyph.valid_glyph { + point_offset := in_glyph.points.len + for i in 0..simple_glyph.contour_ends.len { + in_glyph.contour_ends << u16(simple_glyph.contour_ends[i] + point_offset) + } + + for p in simple_glyph.points { + mut x := f32(p.x) + mut y := f32(p.y) + x = component.matrix[0] * x + component.matrix[1] * y + component.matrix[4] + y = component.matrix[2] * x + component.matrix[3] * y + component.matrix[5] + in_glyph.points << Point{ + x: int(x) + y: int(y) + on_curve: p.on_curve + } + + } + } + tf.pos = old_pos + } + + in_glyph.number_of_contours = i16(in_glyph.contour_ends.len) + + if (flags & tfkc_we_have_instructions) > 0 { + tf.pos = tf.get_u16() + tf.pos + } + + // ok we have a valid glyph + in_glyph.valid_glyph = true +} + +/****************************************************************************** +* +* TTF_File get functions +* +******************************************************************************/ +fn (mut tf TTF_File) get_u8() byte { + x := tf.buf[tf.pos] + tf.pos++ + return byte(x) +} + +fn (mut tf TTF_File) get_i8() i8 { + return i8(tf.get_u8()) +} + +fn (mut tf TTF_File) get_u16() u16 { + x := u16(tf.buf[tf.pos] << u16(8)) | u16(tf.buf[tf.pos + 1]) + tf.pos += 2 + return x +} + +fn (mut tf TTF_File) get_ufword() u16 { + return tf.get_u16() +} + +fn (mut tf TTF_File) get_i16() i16 { + return i16(tf.get_u16()) +} + +fn (mut tf TTF_File) get_fword() i16 { + return tf.get_i16() +} + +fn (mut tf TTF_File) get_u32() u32 { + x :=(u32(tf.buf[tf.pos]) << u32(24)) | + (u32(tf.buf[tf.pos + 1]) << u32(16)) | + (u32(tf.buf[tf.pos + 2]) << u32(8)) | + u32(tf.buf[tf.pos + 3]) + tf.pos += 4 + return x +} + +fn (mut tf TTF_File) get_i32() int { + return int(tf.get_u32()) +} + +fn (mut tf TTF_File) get_2dot14() f32 { + return f32(tf.get_i16()) / f32(i16(1 << 14)) +} + +fn (mut tf TTF_File) get_fixed() f32 { + return f32(tf.get_i32() / f32(1 << 16)) +} + +/*---- restore when MSVC will work again! ---- +fn (mut tf TTF_File) get_string(length int) string { + tmp_pos := tf.pos + tf.pos += u32(length) + unsafe{ + return tos(&tf.buf.data[tmp_pos], length) + } +} +*/ + +fn (mut tf TTF_File) get_string(length int) string { + tmp_pos := tf.pos + mut tmp_txt := strings.new_builder(length) + for _ in 0..length { + tmp_txt.write_b(tf.get_u8()) + } + res_txt := tmp_txt.str() + tf.pos = tmp_pos + u32(length) + return res_txt +} + +fn (mut tf TTF_File) get_unicode_string(length int) string { + mut tmp_txt := strings.new_builder(length) + mut real_len := 0 + + for _ in 0..(length>>1) { + c := tf.get_u16() + c_len := ((0xe5000000>>((c>>3) & 0x1e)) & 3) + 1 + real_len += c_len + if c_len == 1 { + tmp_txt.write_b(byte(c & 0xff)) + } else { + tmp_txt.write_b(byte((c >> 8) & 0xff)) + tmp_txt.write_b(byte(c & 0xff)) + } + //dprintln("c: ${c:c}|${ byte(c &0xff) :c} c_len: ${c_len} str_len: ${real_len} in_len: ${length}") + } + tf.pos += u32(real_len) + res_txt := tmp_txt.str() + //dprintln("get_unicode_string: ${res_txt}") + return res_txt +} + +fn (mut tf TTF_File) get_date() u64 { + // var macTime = this.getUint32() * 0x100000000 + this.getUint32(); + // utcTime = macTime * 1000 + Date.UTC(1904, 1, 1); + // return new Date(utcTime); + + mac_time := u64( (tf.get_u32()) << 32) + u64(tf.get_u32()) + return mac_time +} + +fn (mut tf TTF_File) calc_checksum(offset u32, length u32) u32 { + old_index := tf.pos + mut sum := u64(0) + mut nlongs := int((length + 3) >> 2) + tf.pos = offset + //dprintln("offs: $offset nlongs: $nlongs") + for nlongs > 0 { + sum = sum + u64(tf.get_u32()) + nlongs-- + } + tf.pos = old_index + return u32(sum & u64(0xffff_ffff)) +} + +/****************************************************************************** +* +* Offset_Table +* +******************************************************************************/ +struct Offset_Table { +mut: + checksum u32 + offset u32 + length u32 +} + +fn (mut tf TTF_File) read_offset_tables() { + dprintln("*** READ TABLES OFFSET ***") + tf.pos = 0 + tf.scalar_type = tf.get_u32() + num_tables := tf.get_u16() + tf.search_range = tf.get_u16() + tf.entry_selector= tf.get_u16() + tf.range_shift = tf.get_u16() + + dprintln("scalar_type : [0x$tf.scalar_type.hex()]") + dprintln("num tables : [$num_tables]") + dprintln("search_range : [0x$tf.search_range.hex()]") + dprintln("entry_selector: [0x$tf.entry_selector.hex()]") + dprintln("range_shift : [0x$tf.range_shift.hex()]") + + mut i:= 0 + for i < num_tables { + tag := tf.get_string(4) + tf.tables[tag] = { + checksum: tf.get_u32() + offset: tf.get_u32() + length: tf.get_u32() + } + dprintln("Table: [$tag]") + //dprintln("${tf.tables[tag]}") + + if tag != 'head' { + assert tf.calc_checksum(tf.tables[tag].offset, tf.tables[tag].length) == tf.tables[tag].checksum + } + i++ + } + dprintln("*** END READ TABLES OFFSET ***") +} + +/****************************************************************************** +* +* Head_Table +* +******************************************************************************/ +fn (mut tf TTF_File) read_head_table() { + dprintln("*** READ HEAD TABLE ***") + tf.pos = tf.tables["head"].offset + dprintln("Offset: $tf.pos") + + tf.version = tf.get_fixed() + tf.font_revision = tf.get_fixed() + tf.checksum_adjustment = tf.get_u32() + tf.magic_number = tf.get_u32() + assert tf.magic_number == 0x5f0f3cf5 + tf.flags = tf.get_u16() + tf.units_per_em = tf.get_u16() + tf.created = tf.get_date() + tf.modified = tf.get_date() + tf.x_min = tf.get_i16() + tf.y_min = tf.get_i16() + tf.x_max = tf.get_i16() + tf.y_max = tf.get_i16() + tf.mac_style = tf.get_u16() + tf.lowest_rec_ppem = tf.get_u16() + tf.font_direction_hint = tf.get_i16() + tf.index_to_loc_format = tf.get_i16() + tf.glyph_data_format = tf.get_i16() +} + +/****************************************************************************** +* +* Name_Table +* +******************************************************************************/ +fn (mut tf TTF_File) read_name_table() { + dprintln("*** READ NAME TABLE ***") + assert "name" in tf.tables + table_offset := tf.tables["name"].offset + tf.pos = tf.tables["name"].offset + + format := tf.get_u16() // must be 0 + assert format == 0 + count := tf.get_u16() + string_offset := tf.get_u16() + + for _ in 0..count { + platform_id := tf.get_u16() + /*platform_specific_id :=*/ tf.get_u16() + /*language_id :=*/ tf.get_u16() + name_id := tf.get_u16() + length := tf.get_u16() + offset := tf.get_u16() + + old_pos := tf.pos + tf.pos = table_offset + string_offset + offset + + mut name := "" + if platform_id == 0 || platform_id == 3 { + name = tf.get_unicode_string(length) + } else { + name = tf.get_string(length) + } + //dprintln("Name [${platform_id} / ${platform_specific_id}] id:[$name_id] language:[$language_id] [$name]") + tf.pos = old_pos + + match name_id { + 1 { + tf.font_family = name + } + 2 { + tf.font_sub_family = name + } + 4 { + tf.full_name = name + } + 6 { + tf.postscript_name = name + } + else {} + } + } +} + +/****************************************************************************** +* +* Cmap_Table +* +******************************************************************************/ +fn (mut tf TTF_File) read_cmap_table() { + dprintln("*** READ CMAP TABLE ***") + assert "cmap" in tf.tables + table_offset := tf.tables["cmap"].offset + tf.pos = table_offset + + version := tf.get_u16() // must be 0 + assert version == 0 + number_sub_tables := tf.get_u16() + + // tables must be sorted by platform id and then platform specific + // encoding. + for _ in 0..number_sub_tables { + // platforms are: + // 0 - Unicode -- use specific id 6 for full coverage. 0/4 common. + // 1 - Macintosh (Discouraged) + // 2 - reserved + // 3 - Microsoft + platform_id := tf.get_u16() + platform_specific_id := tf.get_u16() + offset := tf.get_u32() + dprintln("CMap platform_id=${platform_id} specific_id=${platform_specific_id} offset=${offset}") + if platform_id == 3 && platform_specific_id <= 1 { + tf.read_cmap(table_offset + offset) + } + } +} + +fn (mut tf TTF_File) read_cmap(offset u32) { + old_pos := tf.pos + tf.pos = offset + format := tf.get_u16() + length := tf.get_u16() + language := tf.get_u16() + + dprintln(" Cmap format: $format length: $length language: $language") + if format == 0 { + dprintln(" Cmap 0 Init...") + mut cmap := TrueTypeCmap{} + cmap.init_0(mut tf) + tf.cmaps << cmap + } else if format == 4 { + dprintln(" Cmap 4 Init...") + mut cmap := TrueTypeCmap{} + cmap.init_4(mut tf) + tf.cmaps << cmap + } + + tf.pos = old_pos +} + +/****************************************************************************** +* +* CMAPS 0/4 +* +******************************************************************************/ +fn (mut tf TTF_File) map_code(char_code int) u16{ + mut index := 0 + for i in 0..tf.cmaps.len { + mut cmap := tf.cmaps[i] + if cmap.format == 0 { + //dprintln("format 0") + index = cmap.map_0(char_code) + } else if cmap.format == 4 { + //dprintln("format 4") + index = cmap.map_4(char_code, mut tf) + } + } + return u16(index) +} + +fn (mut tm TrueTypeCmap) init_0(mut tf TTF_File) { + tm.format = 0 + for i in 0..256 { + glyph_index := tf.get_u8() + dprintln(" Glyph[$i] = %glyph_index") + tm.arr << glyph_index + } +} + +fn (mut tm TrueTypeCmap) map_0(char_code int) int { + if char_code >= 0 && char_code <= 255 { + //dprintln("charCode $char_code maps to ${tm.arr[char_code]}") + return tm.arr[char_code] + } + return 0 +} + +fn (mut tm TrueTypeCmap) init_4(mut tf TTF_File) { + tm.format = 4 + + // 2x segcount + seg_count := tf.get_u16() >> 1 + /*search_range :=*/ tf.get_u16() + /*entry_selector :=*/ tf.get_u16() + /*range_shift :=*/ tf.get_u16() + + + // Ending character code for each segment, last is 0xffff + for _ in 0..seg_count { + tm.segments << Segment{0, 0, tf.get_u16(), 0} + } + + // reservePAD + tf.get_u16() + + // starting character code for each segment + for i in 0..seg_count { + tm.segments[i].start_code = tf.get_u16() + } + + // Delta for all character codes in segment + for i in 0..seg_count { + tm.segments[i].id_delta = tf.get_u16() + } + + // offset in bytes to glyph indexArray, or 0 + for i in 0..seg_count { + ro := u32(tf.get_u16()) + if ro != 0 { + tm.segments[i].id_range_offset = tf.pos - 2 + ro + } else { + tm.segments[i].id_range_offset = 0 + } + } +/* + // DEBUG LOG + for i in 0..seg_count { + seg := tm.segments[i] + dprintln(" segments[$i] = $seg.start_code $seg.end_code $seg.id_delta $seg.id_range_offset") + } +*/ +} + +fn (mut tm TrueTypeCmap) map_4(char_code int, mut tf TTF_File) int { + //dprintln("HERE map_4 for char [$char_code]") + old_pos := tf.pos + if tm.cache[char_code] == -1 { + //dprintln("Not found, search for it!") + mut found := false + for segment in tm.segments { + if segment.start_code <= char_code && segment.end_code >= char_code { + mut index := (segment.id_delta + char_code) & 0xffff + if segment.id_range_offset > 0 { + glyph_index_address := segment.id_range_offset + 2 * u32(char_code - segment.start_code) + tf.pos = glyph_index_address + index = tf.get_u16() + } + + tm.cache[char_code] = index + found = true + break + } + } + if !found { + tm.cache[char_code] = 0 + } + } + tf.pos = old_pos + return tm.cache[char_code] +} + +/****************************************************************************** +* +* Hhea table +* +******************************************************************************/ +fn (mut tf TTF_File) read_hhea_table() { + dprintln("*** READ HHEA TABLE ***") + assert "hhea" in tf.tables + table_offset := tf.tables["hhea"].offset + tf.pos = table_offset + + /*version :=*/ tf.get_fixed() // 0x00010000 + + tf.ascent = tf.get_fword() + tf.descent = tf.get_fword() + tf.line_gap = tf.get_fword() + tf.advance_width_max = tf.get_ufword() + tf.min_left_side_bearing = tf.get_fword() + tf.min_right_side_bearing = tf.get_fword() + tf.x_max_extent = tf.get_fword() + tf.caret_slope_rise = tf.get_i16() + tf.caret_slope_run = tf.get_i16() + tf.caret_offset = tf.get_fword() + tf.get_i16() // reserved + tf.get_i16() // reserved + tf.get_i16() // reserved + tf.get_i16() // reserved + tf.metric_data_format = tf.get_i16() + tf.num_of_long_hor_metrics = tf.get_u16() +} + +/****************************************************************************** +* +* Kern table +* +******************************************************************************/ +struct Kern0Table { +mut: + swap bool + offset u32 + n_pairs int + kmap map[u32]i16 + old_index int = -1 +} + +fn (mut kt Kern0Table) reset() { + kt.old_index = -1 +} + +fn (mut kt Kern0Table) get(glyph_index int) (int, int) { + mut x := 0 + + if kt.old_index >= 0 { + ch := ((u32(kt.old_index & 0xFFFF) << 16) | u32(glyph_index & 0xFFFF)) + //dprintln("kern_get: $ch") + if ch in kt.kmap { + x = int(kt.kmap[ch]) + } + } + kt.old_index = glyph_index + if kt.swap { + return 0 , x + } + return x, 0 +} + +fn (mut tf TTF_File) create_kern_table0(vertical bool, cross bool) Kern0Table { + offset := tf.pos + n_pairs := tf.get_u16() + search_range := tf.get_u16() + entry_selector := tf.get_u16() + range_shift := tf.get_u16() + dprintln("n_pairs: $n_pairs search_range: $search_range entry_selector: $entry_selector range_shift: $range_shift") + + mut kt0 := Kern0Table{ + swap: (vertical && !cross) || (!vertical && cross) + offset: offset + n_pairs: n_pairs + } + + for _ in 0..n_pairs { + left := tf.get_u16() + right := tf.get_u16() + value := tf.get_fword() + tmp_index := (u32(left) << 16) | u32(right) + kt0.kmap[tmp_index] = value + //dprintln("index: ${tmp_index.hex()} val: ${value.hex()}") + } + kt0.old_index = -1 + return kt0 +} + +fn (mut tf TTF_File) read_kern_table() { + dprintln("*** READ KERN TABLE ***") + if !("kern" in tf.tables){ + return + } + table_offset := tf.tables["kern"].offset + tf.pos = table_offset + + version := tf.get_u16() // must be 0 + assert version == 0 // must be 0 + n_tables := tf.get_u16() + + dprintln("Kern Table version: $version Kern nTables: $n_tables") + + for _ in 0..n_tables{ + st_version := tf.get_u16() // sub table version + length := tf.get_u16() + coverage := tf.get_u16() + format := coverage >> 8 + cross := coverage & 4 + vertical := (coverage & 0x1) == 0 + dprintln("Kerning subtable version [$st_version] format [$format] length [$length] coverage: [${coverage.hex()}]") + if format == 0 { + dprintln("kern format: 0") + kern := tf.create_kern_table0(vertical, cross != 0) + tf.kern << kern + } else { + dprintln("Unknown format -- skip") + tf.pos = tf.pos + length + } + } +} + +fn (mut tf TTF_File) reset_kern() { + for i in 0..tf.kern.len { + tf.kern[i].reset() + } +} + +fn (mut tf TTF_File) next_kern(glyph_index int) (int, int){ + mut x := 0 + mut y := 0 + for i in 0..tf.kern.len { + tmp_x, tmp_y := tf.kern[i].get(glyph_index) + x = x + tmp_x + y = y + tmp_y + } + return x, y +} + + +/****************************************************************************** +* +* TTF_File Utility +* +******************************************************************************/ +/* +fn (tf TTF_File) get_info_string() string{ + txt := "----- Font Info ----- +version: $tf.version +font_revision: $tf.font_revision +magic_number : ${tf.magic_number.hex()} +flags : ${tf.flags.hex()} +created : ${tf.created} +modified : ${tf.modified} +box : [xm:${tf.x_min}, ym:${tf.y_min}, xM:${tf.x_max}, yM:${tf.y_max}] +mac_style : ${tf.mac_style} +----------------------- +" + return txt +} +*/ + + +/****************************************************************************** +* +* TTF_File test +* +******************************************************************************/ +fn tst(){ + mut tf := TTF_File{} + + tf.buf = [ + byte(0xFF), // 8 bit + 0xF1, 0xF2, // 16 bit + 0x81, 0x23, 0x45, 0x67, // 32 bit + 0x12, 0x34, 0x12, 0x34, // get_2dot14 16 bit + 0x12, 0x34, 0x12, 0x34 // get_fixed 32 bit int + ] + assert tf.get_u8().hex() == "ff" + assert tf.get_u16().hex() == "f1f2" + assert tf.get_u32().hex() == "81234567" + + dprintln("buf len: ${tf.buf.len}") + //dprintln( tf.get_u8().hex() ) + //dprintln( tf.get_u16().hex() ) + //dprintln( tf.get_u32().hex() ) + //dprintln( tf.get_2dot14() ) + //dprintln( tf.get_fixed() ) +} \ No newline at end of file diff --git a/vlib/x/ttf/ttf_test.v b/vlib/x/ttf/ttf_test.v new file mode 100644 index 0000000000..c7f9c403e9 --- /dev/null +++ b/vlib/x/ttf/ttf_test.v @@ -0,0 +1,242 @@ +/********************************************************************** +* +* BMP render module utility functions +* +* Copyright (c) 2021 Dario Deledda. All rights reserved. +* Use of this source code is governed by an MIT license +* that can be found in the LICENSE file. +* +* Note: +* +* TODO: +* - manage text directions R to L +**********************************************************************/ +import ttf +import os +import strings + +const ( + font_path = "Qarmic_sans_Abridged.ttf" + create_data = false // use true to generate binary data for this test file +) + +fn save_raw_data_as_array(buf_bin []byte, file_name string) { + mut buf := strings.new_builder(buf_bin.len * 5) + for x in buf_bin { + buf.write("0x${x:02x},") + } + os.write_file_array(file_name, buf.buf) +} + +fn test_main() { + mut tf := ttf.TTF_File{} + if create_data == true { + tf.buf = os.read_bytes(font_path) or { panic(err) } + println("TrueTypeFont file [$font_path] len: ${tf.buf.len}") + save_raw_data_as_array(tf.buf, "test_ttf_Font_arr.bin") + } else { + tf.buf = font_bytes + } + tf.init() + //println("Unit per EM: $tf.units_per_em") + + w := 64 + h := 32 + bp := 4 + sz := w * h* bp + + font_size := 20 + device_dpi := 72 + scale := f32(font_size * device_dpi) / f32(72 * tf.units_per_em) + + mut bmp := ttf.BitMap{ + tf : &tf + buf : malloc(sz) + buf_size : sz + scale : scale + width : w + height : h + } + + y_base := int((tf.y_max - tf.y_min) * bmp.scale) + bmp.clear() + bmp.set_pos(0,y_base) + bmp.init_filler() + bmp.draw_text("Test Text") + + mut test_buf := get_raw_data(test_data) + if create_data == true { + bmp.save_as_ppm("test_ttf.ppm") + bmp.save_raw_data("test_ttf.bin") + test_buf = os.read_bytes("test_ttf.bin") or { panic(err) } + } + + ram_buf := bmp.get_raw_bytes() + assert ram_buf.len == test_buf.len + for i in 0..ram_buf.len { + if test_buf[i] != ram_buf[i] { + assert false + } + } +} + +fn get_raw_data(data string) []byte{ + mut buf := []byte{} + mut c := 0 + mut b := 0 + for ch in data { + if ch >= `0` && ch <= `9` { + b = b << 4 + b += int(ch - `0`) + c++ + } else if ch >= `a` && ch <= `f` { + b = b << 4 + b += int(ch - `a` + 10) + c++ + } + + if c == 2 { + buf << byte(b) + b = 0 + c = 0 + } + } + return buf +} + +const( + test_data =" +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +00bf bfbf bfbf bfbf bfbf bfbf bf00 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +00bf bfbf bfbf bfbf bfbf bfbf bf00 0000 +bfff ffff ffff ffff ffff ffff ffbf 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +bfff ffff ffff ffff ffff ffff ffbf 0000 +00bf ffff ffbf ffff bfff ffff bf00 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +00bf ffff ffbf ffff bfff ffff bf00 0000 +0000 0000 00bf ffff bf00 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +bf00 0000 0000 0000 0000 0000 0000 0000 +0000 0000 00bf ffff bf00 0000 0000 0000 +0000 0000 00bf ffff bf00 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 00bf +ffbf 0000 0000 0000 0000 0000 0000 0000 +0000 0000 00bf ffff bf00 0000 0000 0000 +0000 0000 00bf ffff bf00 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 00bf +ffbf 0000 0000 0000 0000 0000 0000 0000 +0000 0000 00bf ffff bf00 0000 0000 0000 +0000 0000 00bf ffff bf00 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 bfbf +ffbf bfbf bf00 0000 0000 0000 0000 0000 +0000 0000 00bf ffff bf00 0000 0000 0000 +0000 0000 00bf ffff bf00 0000 0032 72bf +bfbf 0000 0000 bfbf bfbf 5400 00bf ffff +ffff ffff ffbf 0000 0000 0000 0000 0000 +0000 0000 00bf ffff bf00 0000 0032 72bf +0000 0000 00bf ffff bf00 0065 9999 ffff +ffff bf00 00bf ffff ffff ff7f 0000 bfff +bfff bfff bf00 0000 0000 0000 0000 0000 +0000 0000 00bf ffff bf00 0065 9999 6500 +0000 0000 00bf ffff bf00 bfff ffff ffbf +ffff ffbf bfff bfff bfbf ffff bf00 bfff +bf00 0000 0000 0000 0000 0000 0000 0000 +0000 0000 00bf ffff bf00 bf72 3300 7fbf +0000 0000 00bf ffff bf7f 5fff ffbf 3f7f +8fbf ffbf ffbf 5500 0000 5fbf 0000 bfff +bf00 0000 0000 0000 0000 0000 0000 0000 +0000 0000 00bf ffff bf7f 5fff ffbf 3f7f +0000 0000 00bf ffff bfbf ffbf bfbf ffff +ffff ffbf ffff ff7f 0000 0000 0000 bfff +bf00 0000 0000 0000 0000 0000 0000 0000 +0000 0000 00bf ffff bfbf 00bf bfbf 8f5f +0000 0000 00bf ffff 7f5f ffff ffff ffff +ffff ffbf 5fbf ffff bfbf bfbf 0000 bfff +bf00 0000 0000 0000 0000 0000 0000 0000 +0000 0000 00bf ffff 7f5f 0000 0000 0000 +0000 0000 00bf ffff bfff bfff ffbf ffff +ffff ffbf 0000 5fbf ffff ffff bf00 bfff +bf00 0000 0000 0000 0000 0000 0000 0000 +0000 0000 00bf ffff bfff bfff ffbf ffff +0000 0000 00bf ffff bfff bf00 0000 0000 +0000 0000 0000 0000 7f7f ffff bf00 bfff +bf00 0000 bf00 0000 0000 0000 0000 0000 +0000 0000 00bf ffff bfff bf00 0000 0000 +0000 0000 00bf ffff bfff bf00 0000 0000 +0000 bf00 bf00 0000 0055 bfff ffbf bfff +ff7f 00bf ff5f 0000 0000 0000 0000 0000 +0000 0000 00bf ffff bfff bf00 0000 0000 +0000 0000 00bf ffff bfbf ffbf 0000 0055 +7fbf ffbf ffbf 7f55 00bf ffff bf00 7f5f +ff7f 7f5f ffbf 0000 0000 0000 0000 0000 +0000 0000 00bf ffff bfbf ffbf 0000 0055 +0000 0000 00bf ffff bfbf ffff bfbf bfff +ffff bfbf ffff ffff ffff ffff bf00 00bf +ffff ffff ffbf 0000 0000 0000 0000 0000 +0000 0000 00bf ffff bfbf 0000 bfbf bf7f +0000 0000 00bf ffff bf00 bfff ffff ffff +ffbf 0000 bfbf ffff ffff bfbf 0000 00bf +ffbf ffff bf00 0000 0000 0000 0000 0000 +0000 0000 00bf ffff bf00 bf00 0000 3f7f +0000 0000 0000 5fbf 0000 00bf ffbf 8f5f +3f00 0000 0000 5fbf bf5f 0000 0000 0000 +0000 bf5f 0000 0000 0000 0000 0000 0000 +0000 0000 0000 5fbf 0000 00bf ffbf 8f5f +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +" + +font_bytes = [ +byte(0x00),0x01,0x00,0x00,0x00,0x0c,0x00,0x80,0x00,0x03,0x00,0x40,0x4f,0x53,0x2f,0x32,0x41,0x98,0xb7,0x90,0x00,0x00,0x01,0x48,0x00,0x00,0x00,0x56,0x63,0x6d,0x61,0x70,0x53,0x38,0xf9,0xae,0x00,0x00,0x03,0x60,0x00,0x00,0x02,0xa4,0x67,0x61,0x73,0x70,0xff,0xff,0x00,0x03,0x00,0x00,0x3e,0xf4,0x00,0x00,0x00,0x08,0x67,0x6c,0x79,0x66,0x95,0xf3,0xc8,0x23,0x00,0x00,0x06,0xe8,0x00,0x00,0x2f,0x6c,0x68,0x65,0x61,0x64,0xf1,0x64,0x88,0x06,0x00,0x00,0x00,0xcc,0x00,0x00,0x00,0x36,0x68,0x68,0x65,0x61,0x11,0x4c,0x06,0xc9,0x00,0x00,0x01,0x04,0x00,0x00,0x00,0x24,0x68,0x6d,0x74,0x78,0x03,0x08,0x1c,0x4d,0x00,0x00,0x01,0xa0,0x00,0x00,0x01,0xc0,0x6b,0x65,0x72,0x6e,0xe3,0x4a,0xe3,0x1a,0x00,0x00,0x36,0x54,0x00,0x00,0x02,0x22,0x6c,0x6f,0x63,0x61,0xa1,0xec,0x96,0x76,0x00,0x00,0x06,0x04,0x00,0x00,0x00,0xe2,0x6d,0x61,0x78,0x70,0x00,0x7b,0x00,0x9a,0x00,0x00,0x01,0x28,0x00,0x00,0x00,0x20,0x6e,0x61,0x6d,0x65,0x86,0x7c,0x31,0x7d,0x00,0x00,0x38,0x78,0x00,0x00,0x05,0x5e,0x70,0x6f,0x73,0x74,0x21,0x0a,0xb6,0x4f,0x00,0x00,0x3d,0xd8,0x00,0x00,0x01,0x1a,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x17,0x61,0x7a,0x59,0x5f,0x0f,0x3c,0xf5,0x00,0x0b,0x08,0x00,0x00,0x00,0x00,0x00,0xc4,0x10,0x0e,0x69,0x00,0x00,0x00,0x00,0xc6,0x1e,0x2e,0xbf,0xfe,0xb5,0xfd,0xbd,0x09,0x63,0x08,0x26,0x00,0x00,0x00,0x06,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x09,0x31,0xfd,0xbd,0x00,0x00,0x09,0x62,0xfe,0xb5,0xff,0x39,0x09,0x63,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x01,0x00,0x00,0x00,0x70,0x00,0x68,0x00,0x05,0x00,0x31,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x01,0x00,0x01,0x04,0x34,0x01,0x90,0x00,0x05,0x00,0x08,0x05,0x9a,0x05,0x33,0x00,0x00,0x01,0x1b,0x05,0x9a,0x05,0x33,0x00,0x00,0x03,0xd1,0x00,0x66,0x02,0x12,0x00,0x00,0x02,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0xa7,0x50,0x00,0x00,0x4a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x4c,0x20,0x20,0x00,0x40,0x00,0x20,0x22,0x19,0x07,0x47,0xfd,0xe7,0x00,0xcd,0x09,0x31,0x02,0x43,0x20,0x00,0x01,0x11,0x41,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x64,0x00,0x00,0x00,0x00,0x01,0xfc,0x00,0x00,0x03,0x7d,0x00,0x00,0x02,0xb1,0x00,0xce,0x02,0xd7,0x00,0x64,0x05,0x0a,0x00,0x41,0x04,0xf9,0x00,0x45,0x06,0xbd,0x00,0x20,0x07,0x03,0x00,0x92,0x01,0x89,0x00,0x64,0x02,0xaa,0x00,0x7d,0x02,0xaa,0x00,0x51,0x03,0x1d,0x00,0x4c,0x04,0xac,0x00,0xc0,0x02,0x39,0x00,0x9e,0x03,0x14,0x00,0x14,0x01,0xff,0x00,0x9e,0x03,0x3c,0xff,0xf7,0x04,0x73,0x00,0x0d,0x04,0x73,0x00,0xa9,0x04,0x73,0x00,0x28,0x04,0x73,0x00,0x20,0x04,0x73,0x00,0x00,0x04,0x73,0x00,0x35,0x04,0x73,0x00,0x0a,0x04,0x73,0x00,0x1a,0x04,0x73,0x00,0x11,0x04,0x73,0x00,0x21,0x01,0xff,0x00,0x9e,0x01,0xff,0x00,0x9e,0x04,0xac,0x00,0xc9,0x04,0xac,0x00,0xc0,0x04,0xac,0x00,0xc9,0x04,0x73,0x00,0xbc,0x06,0x44,0x00,0x40,0x06,0xa5,0x00,0x45,0x06,0x8f,0x00,0x57,0x06,0x12,0x00,0x3c,0x06,0x4a,0x00,0x34,0x05,0xbd,0x00,0x38,0x04,0xb2,0x00,0x35,0x07,0x0d,0x00,0x1e,0x06,0xde,0x00,0x1d,0x02,0xc6,0x00,0x33,0x06,0x92,0x00,0x51,0x06,0x61,0xff,0xf9,0x05,0xa0,0x00,0x43,0x09,0x26,0x00,0x3d,0x07,0x06,0x00,0x3d,0x07,0xa7,0x00,0x1a,0x06,0x50,0x00,0x3d,0x07,0x93,0x00,0x24,0x06,0x5c,0x00,0x27,0x06,0x28,0x00,0x2a,0x05,0x97,0x00,0x01,0x06,0x3f,0x00,0x16,0x06,0x4c,0x00,0x02,0x09,0x62,0x00,0x02,0x05,0x68,0x00,0x12,0x05,0xe9,0x00,0x21,0x05,0xce,0x00,0x31,0x03,0x20,0x00,0xaa,0x03,0x0b,0x00,0x0f,0x03,0x1a,0x00,0x50,0x04,0x2b,0x00,0x00,0x04,0x73,0xff,0xa6,0x02,0xaa,0x00,0x4a,0x05,0x02,0x00,0x3e,0x05,0x15,0x00,0x4b,0x04,0x49,0x00,0x39,0x05,0x35,0x00,0x34,0x04,0xc0,0x00,0x39,0x02,0x70,0xff,0xc6,0x05,0x02,0x00,0x27,0x04,0xc0,0x00,0x42,0x02,0x73,0x00,0x52,0x02,0x12,0xfe,0xb5,0x04,0x52,0x00,0x3e,0x02,0x3d,0x00,0x38,0x07,0x96,0x00,0x46,0x04,0xd4,0x00,0x46,0x05,0x51,0x00,0x2d,0x05,0x0a,0x00,0x45,0x05,0x43,0x00,0x27,0x03,0x28,0x00,0x33,0x04,0x49,0x00,0x45,0x03,0x94,0x00,0x12,0x04,0xa7,0x00,0x35,0x04,0x22,0x00,0x11,0x06,0x6d,0x00,0x08,0x04,0x22,0x00,0x1c,0x04,0x9e,0x00,0x32,0x03,0xca,0x00,0x32,0x03,0xf6,0x00,0x87,0x02,0x3b,0x00,0x9c,0x04,0x2d,0x00,0x33,0x05,0xc5,0x00,0x07,0x04,0x00,0x01,0x00,0x03,0x2f,0x00,0x16,0x03,0xf6,0x00,0x57,0x03,0x14,0x00,0x34,0x02,0xa2,0x00,0x3c,0x04,0x73,0x00,0x28,0x04,0x73,0x00,0x20,0x04,0x00,0x00,0xd3,0x02,0xc4,0x00,0x9e,0x04,0x00,0x01,0x58,0x04,0x73,0x00,0xbd,0x06,0xac,0x00,0x1b,0x06,0x52,0x00,0x1a,0x06,0xac,0x00,0x20,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x1c,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0xa0,0x00,0x03,0x00,0x01,0x00,0x00,0x00,0x1c,0x00,0x04,0x00,0x84,0x00,0x00,0x00,0x1a,0x00,0x10,0x00,0x03,0x00,0x0a,0x00,0x7a,0x00,0x7e,0x00,0xa3,0x00,0xa8,0x00,0xaa,0x00,0xad,0x00,0xb0,0x00,0xb4,0x00,0xb9,0x00,0xbe,0x03,0x7e,0x22,0x19,0xff,0xff,0x00,0x00,0x00,0x20,0x00,0x7e,0x00,0xa0,0x00,0xa8,0x00,0xaa,0x00,0xac,0x00,0xaf,0x00,0xb2,0x00,0xb7,0x00,0xbc,0x03,0x7e,0x22,0x19,0xff,0xff,0xff,0xe3,0xff,0xe0,0x00,0x00,0xff,0xba,0xff,0xb9,0x00,0x00,0xff,0xb6,0xff,0xb5,0xff,0xb3,0xff,0xb1,0xfc,0xa0,0xde,0x51,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x16,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x5f,0x00,0x60,0x00,0x61,0x00,0x64,0x00,0x10,0x00,0x06,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0xfd,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x04,0x00,0x05,0x00,0x06,0x00,0x07,0x00,0x08,0x00,0x09,0x00,0x0a,0x00,0x0b,0x00,0x0c,0x00,0x0d,0x00,0x0e,0x00,0x0f,0x00,0x10,0x00,0x11,0x00,0x12,0x00,0x13,0x00,0x14,0x00,0x15,0x00,0x16,0x00,0x17,0x00,0x18,0x00,0x19,0x00,0x1a,0x00,0x1b,0x00,0x1c,0x00,0x1d,0x00,0x1e,0x00,0x1f,0x00,0x20,0x00,0x21,0x00,0x22,0x00,0x23,0x00,0x24,0x00,0x25,0x00,0x26,0x00,0x27,0x00,0x28,0x00,0x29,0x00,0x2a,0x00,0x2b,0x00,0x2c,0x00,0x2d,0x00,0x2e,0x00,0x2f,0x00,0x30,0x00,0x31,0x00,0x32,0x00,0x33,0x00,0x34,0x00,0x35,0x00,0x36,0x00,0x37,0x00,0x38,0x00,0x39,0x00,0x3a,0x00,0x3b,0x00,0x3c,0x00,0x3d,0x00,0x3e,0x00,0x3f,0x00,0x40,0x00,0x41,0x00,0x42,0x00,0x43,0x00,0x44,0x00,0x45,0x00,0x46,0x00,0x47,0x00,0x48,0x00,0x49,0x00,0x4a,0x00,0x4b,0x00,0x4c,0x00,0x4d,0x00,0x4e,0x00,0x4f,0x00,0x50,0x00,0x51,0x00,0x52,0x00,0x53,0x00,0x54,0x00,0x55,0x00,0x56,0x00,0x57,0x00,0x58,0x00,0x59,0x00,0x5a,0x00,0x5b,0x00,0x5c,0x00,0x5d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x00,0x60,0x00,0x61,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x69,0x00,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5f,0x00,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6b,0x00,0x00,0x00,0x56,0x00,0x56,0x00,0x56,0x00,0x56,0x00,0x7c,0x00,0xa4,0x01,0x34,0x01,0xda,0x02,0x4a,0x02,0xa6,0x02,0xbe,0x02,0xea,0x03,0x16,0x03,0x58,0x03,0x80,0x03,0x98,0x03,0xb0,0x03,0xc2,0x03,0xe0,0x04,0x12,0x04,0x38,0x04,0x76,0x04,0xc0,0x04,0xfa,0x05,0x48,0x05,0x8c,0x05,0xbc,0x06,0x0a,0x06,0x48,0x06,0x68,0x06,0x8c,0x06,0xb4,0x06,0xdc,0x07,0x04,0x07,0x40,0x07,0xb2,0x07,0xea,0x08,0x3c,0x08,0x72,0x08,0xae,0x08,0xde,0x09,0x08,0x09,0x52,0x09,0x8e,0x09,0xb0,0x09,0xea,0x0a,0x2c,0x0a,0x52,0x0a,0x8a,0x0a,0xb6,0x0b,0x04,0x0b,0x3c,0x0b,0x98,0x0b,0xda,0x0c,0x1c,0x0c,0x3a,0x0c,0x6e,0x0c,0x96,0x0c,0xe0,0x0d,0x1c,0x0d,0x48,0x0d,0x76,0x0d,0x98,0x0d,0xb6,0x0d,0xd8,0x0d,0xd8,0x0d,0xee,0x0e,0x0c,0x0e,0x54,0x0e,0x8e,0x0e,0xc0,0x0f,0x00,0x0f,0x3c,0x0f,0x70,0x0f,0xbc,0x0f,0xf0,0x10,0x1e,0x10,0x52,0x10,0x88,0x10,0xaa,0x10,0xfa,0x11,0x30,0x11,0x6a,0x11,0xa8,0x11,0xee,0x12,0x1a,0x12,0x56,0x12,0x90,0x12,0xc6,0x12,0xf2,0x13,0x3a,0x13,0x78,0x13,0xba,0x13,0xe4,0x14,0x0e,0x14,0x18,0x14,0x74,0x14,0xd0,0x14,0xee,0x15,0x00,0x15,0x12,0x15,0x30,0x15,0x56,0x15,0x94,0x15,0xde,0x15,0xfa,0x16,0x0e,0x16,0x36,0x16,0x5c,0x16,0xc4,0x17,0x2e,0x17,0xb6,0x00,0x00,0x00,0x04,0x00,0x64,0x00,0x00,0x03,0x9c,0x05,0x9a,0x00,0x03,0x00,0x07,0x00,0x24,0x00,0x38,0x00,0x00,0x33,0x11,0x21,0x11,0x25,0x21,0x11,0x21,0x17,0x36,0x37,0x36,0x33,0x32,0x16,0x15,0x14,0x06,0x07,0x0e,0x01,0x15,0x14,0x17,0x23,0x26,0x35,0x34,0x12,0x35,0x34,0x26,0x23,0x22,0x07,0x06,0x07,0x13,0x37,0x36,0x33,0x32,0x1f,0x01,0x16,0x15,0x14,0x0f,0x01,0x06,0x23,0x22,0x2f,0x01,0x26,0x35,0x34,0x64,0x03,0x38,0xfc,0xfa,0x02,0xd4,0xfd,0x2c,0xaf,0x1f,0x1b,0x35,0x3b,0x5c,0x70,0x2e,0x40,0x3f,0x48,0x18,0x20,0x23,0xa3,0x42,0x3a,0x26,0x1f,0x1a,0x1e,0x40,0x39,0x0b,0x09,0x0a,0x0c,0x38,0x09,0x0a,0x38,0x0e,0x07,0x0b,0x09,0x3d,0x07,0x05,0x9a,0xfa,0x66,0x32,0x05,0x36,0xec,0x1c,0x0f,0x1e,0x5f,0x50,0x31,0x63,0x50,0x50,0x68,0x2f,0x26,0x5f,0x61,0x33,0x4c,0x01,0x1c,0x4b,0x39,0x42,0x11,0x0f,0x19,0xfc,0xff,0x3a,0x0a,0x0b,0x3c,0x0b,0x09,0x0b,0x0b,0x3e,0x0e,0x0a,0x47,0x09,0x09,0x0a,0x00,0x02,0x00,0xce,0xff,0xfe,0x01,0xd2,0x06,0xc1,0x00,0x0b,0x00,0x13,0x00,0x00,0x01,0x26,0x35,0x02,0x27,0x36,0x33,0x16,0x17,0x14,0x03,0x14,0x02,0x37,0x32,0x17,0x14,0x07,0x26,0x27,0x01,0x3e,0x65,0x07,0x01,0x01,0x70,0x70,0x05,0x0a,0xde,0x76,0x83,0x0a,0x7b,0x7f,0x0a,0x02,0x03,0x19,0x5c,0x03,0x82,0x4c,0x7b,0x02,0x7c,0x50,0xfc,0x7e,0x5d,0xfe,0xeb,0x0a,0x7f,0x89,0x03,0x01,0x7a,0x00,0x00,0x02,0x00,0x64,0x05,0x0b,0x02,0x58,0x07,0x41,0x00,0x09,0x00,0x13,0x00,0x00,0x00,0x17,0x03,0x06,0x07,0x26,0x35,0x03,0x36,0x33,0x04,0x17,0x03,0x06,0x07,0x26,0x35,0x03,0x36,0x33,0x01,0x23,0x09,0x0d,0x01,0x57,0x57,0x0c,0x14,0x52,0x01,0x85,0x09,0x0d,0x01,0x57,0x57,0x0c,0x14,0x52,0x07,0x3d,0x51,0xfe,0x8a,0x6a,0x01,0x01,0x6f,0x01,0x75,0x51,0x04,0x51,0xfe,0x8a,0x6a,0x01,0x01,0x6f,0x01,0x75,0x51,0x00,0x00,0x02,0x00,0x41,0xff,0xf8,0x04,0xbb,0x06,0x5c,0x00,0x09,0x00,0x5a,0x00,0x00,0x01,0x06,0x07,0x06,0x07,0x36,0x37,0x13,0x36,0x37,0x05,0x07,0x26,0x27,0x36,0x37,0x32,0x37,0x32,0x37,0x36,0x37,0x36,0x33,0x16,0x17,0x06,0x07,0x36,0x37,0x36,0x37,0x36,0x33,0x16,0x17,0x06,0x07,0x16,0x33,0x16,0x17,0x06,0x07,0x06,0x07,0x26,0x27,0x26,0x27,0x06,0x07,0x06,0x07,0x16,0x33,0x16,0x17,0x06,0x07,0x06,0x07,0x26,0x27,0x26,0x23,0x02,0x07,0x26,0x35,0x36,0x13,0x07,0x02,0x07,0x26,0x35,0x34,0x13,0x07,0x26,0x27,0x36,0x37,0x32,0x37,0x36,0x37,0x13,0x36,0x37,0x02,0x5b,0x16,0x1b,0x17,0x16,0x4b,0x5b,0x5c,0x06,0x06,0xfe,0x5d,0x6a,0x46,0x04,0x0e,0x3d,0x23,0x68,0x1f,0x26,0x25,0x16,0x22,0x36,0x45,0x08,0x02,0x2f,0x50,0x61,0x23,0x16,0x22,0x35,0x45,0x08,0x02,0x2e,0x77,0x1d,0x3d,0x0e,0x02,0x1c,0x0c,0x1d,0x0f,0x10,0x73,0x28,0x16,0x1d,0x16,0x15,0x7a,0x22,0x3d,0x0e,0x02,0x11,0x08,0x27,0x13,0x14,0x76,0x2e,0x75,0x5f,0x52,0x01,0x5f,0x9a,0x74,0x5e,0x51,0x5b,0x83,0x46,0x04,0x0e,0x3d,0x29,0x8d,0x01,0x01,0x5e,0x05,0x05,0x04,0x37,0x68,0x7e,0x75,0x65,0x01,0x02,0x01,0x89,0x1b,0x1b,0x0c,0x08,0x0c,0x51,0x50,0x04,0x02,0x01,0xb2,0x98,0x39,0x04,0x60,0x33,0xe8,0x02,0x02,0xaa,0x93,0x39,0x03,0x61,0x32,0xe2,0x04,0x04,0x50,0x32,0x18,0x12,0x06,0x04,0x03,0x0f,0x01,0x6b,0x85,0x70,0x62,0x03,0x04,0x50,0x26,0x17,0x1f,0x07,0x05,0x03,0x0e,0xfe,0x23,0x01,0x03,0x4c,0x4b,0x01,0x41,0x03,0xfe,0x2e,0x01,0x02,0x4c,0x4b,0x01,0x33,0x09,0x0b,0x52,0x4f,0x04,0x03,0x03,0x04,0x01,0x8d,0x16,0x15,0x00,0x00,0x05,0x00,0x45,0xfe,0xc4,0x04,0xa5,0x07,0x56,0x00,0x44,0x00,0x4b,0x00,0x52,0x00,0x5c,0x00,0x67,0x00,0x00,0x01,0x36,0x37,0x32,0x17,0x11,0x36,0x37,0x16,0x17,0x11,0x16,0x17,0x16,0x15,0x14,0x07,0x06,0x23,0x22,0x27,0x26,0x27,0x11,0x16,0x17,0x16,0x15,0x02,0x05,0x11,0x06,0x07,0x26,0x27,0x11,0x06,0x07,0x23,0x26,0x27,0x11,0x06,0x07,0x26,0x27,0x11,0x26,0x27,0x26,0x35,0x37,0x36,0x33,0x32,0x17,0x16,0x17,0x11,0x24,0x03,0x37,0x12,0x25,0x11,0x36,0x37,0x16,0x17,0x01,0x36,0x37,0x36,0x35,0x34,0x27,0x01,0x06,0x07,0x06,0x15,0x14,0x17,0x05,0x26,0x27,0x26,0x27,0x11,0x16,0x17,0x36,0x37,0x11,0x26,0x2b,0x01,0x06,0x07,0x11,0x16,0x17,0x16,0x17,0x02,0x2a,0x1c,0x1e,0x45,0x31,0x01,0x47,0x47,0x01,0x66,0x3c,0x62,0x08,0x11,0x1d,0x2e,0x4a,0x22,0x34,0x91,0x3c,0x6e,0x0b,0xfe,0xd0,0x01,0x47,0x47,0x01,0x14,0x21,0x49,0x19,0x19,0x01,0x3d,0x51,0x01,0x55,0x5c,0xa4,0x11,0x14,0x15,0x44,0x51,0x39,0x4d,0xfe,0xe5,0x14,0x02,0x18,0x01,0x15,0x01,0x51,0x3d,0x01,0x01,0x40,0x90,0x0e,0x01,0x9f,0xfe,0x30,0x83,0x03,0x05,0x8b,0x01,0x40,0x3d,0x5a,0x0d,0x0c,0x26,0x2a,0x39,0x27,0x2e,0x40,0x03,0x21,0x1e,0x12,0x14,0x50,0x3a,0x06,0x0f,0x02,0x02,0x09,0x01,0x09,0x42,0x01,0x01,0x43,0xfe,0xd9,0x22,0x3f,0x69,0x48,0x14,0x12,0x20,0x54,0x27,0x1c,0xfe,0x69,0x27,0x49,0x86,0xd4,0xfe,0xcc,0x5d,0xfe,0xcd,0x40,0x01,0x01,0x44,0x01,0x13,0x04,0x03,0x01,0x03,0xfe,0xec,0x40,0x01,0x01,0x44,0x01,0x2f,0x29,0x5a,0x9f,0xae,0x17,0x0e,0x96,0x68,0x35,0x02,0x15,0x41,0x01,0x14,0x2b,0x01,0x1e,0x4c,0x01,0x1a,0x42,0x01,0x01,0x43,0xf9,0xe3,0x3f,0x8a,0x09,0x09,0xa3,0x4b,0x02,0x83,0x3c,0x7a,0x14,0x12,0x6c,0x28,0xe9,0x10,0x04,0x01,0x01,0xfd,0xcf,0x07,0x03,0x03,0x09,0x04,0x90,0x0e,0x04,0x06,0xfe,0x5b,0x02,0x01,0x04,0x0a,0x00,0x00,0x05,0x00,0x20,0xff,0xeb,0x06,0x76,0x06,0x25,0x00,0x0d,0x00,0x19,0x00,0x27,0x00,0x33,0x00,0x41,0x00,0x00,0x01,0x17,0x1e,0x01,0x17,0x14,0x06,0x07,0x27,0x2e,0x01,0x27,0x3e,0x01,0x03,0x16,0x1f,0x01,0x36,0x3f,0x01,0x34,0x26,0x27,0x23,0x06,0x01,0x17,0x1e,0x01,0x17,0x14,0x06,0x07,0x27,0x2e,0x01,0x27,0x3e,0x01,0x03,0x16,0x1f,0x01,0x36,0x3f,0x01,0x34,0x26,0x27,0x23,0x06,0x00,0x37,0x32,0x17,0x14,0x07,0x01,0x06,0x07,0x26,0x27,0x36,0x37,0x01,0x01,0x82,0x2e,0x7d,0xe1,0x1a,0xc0,0xb8,0x22,0xa1,0xc8,0x05,0x09,0xae,0x28,0x0c,0xc4,0x2b,0xb3,0x2a,0x05,0x93,0x63,0x1c,0xb4,0x04,0x0a,0x2d,0x7e,0xe1,0x1a,0xc1,0xb8,0x21,0xa1,0xc8,0x05,0x08,0xae,0x28,0x0d,0xc4,0x2a,0xb4,0x2a,0x05,0x93,0x63,0x1c,0xb4,0x01,0x96,0x3d,0x27,0x13,0x32,0xfb,0x52,0x44,0x39,0x32,0x0b,0x07,0x3e,0x04,0xbd,0x06,0x25,0x02,0x08,0xbc,0xbd,0xb6,0xc9,0x0d,0x05,0x11,0xd3,0xc1,0x95,0xc6,0xfe,0x99,0xd3,0x3a,0x06,0x12,0xac,0x1b,0x77,0x99,0x0a,0x18,0xfd,0xa7,0x01,0x08,0xbd,0xbd,0xb6,0xc9,0x0c,0x04,0x11,0xd3,0xc1,0x95,0xc7,0xfe,0x98,0xd3,0x39,0x07,0x12,0xac,0x1c,0x77,0x99,0x09,0x17,0x03,0x94,0x03,0x3d,0x43,0x2a,0xfa,0xd1,0x45,0x09,0x09,0x50,0x3d,0x34,0x05,0x37,0x00,0x03,0x00,0x92,0xff,0xf7,0x06,0xa0,0x07,0x4a,0x00,0x21,0x00,0x29,0x00,0x31,0x00,0x00,0x24,0x17,0x06,0x07,0x26,0x2f,0x01,0x06,0x05,0x23,0x24,0x03,0x35,0x12,0x01,0x26,0x35,0x36,0x25,0x33,0x04,0x13,0x06,0x07,0x16,0x13,0x36,0x13,0x34,0x37,0x16,0x15,0x02,0x07,0x01,0x06,0x07,0x16,0x17,0x36,0x37,0x34,0x03,0x04,0x03,0x12,0x05,0x36,0x37,0x02,0x06,0x46,0x14,0x03,0x70,0x50,0x2b,0x2a,0xc3,0xfe,0xcf,0x5b,0xfd,0xb4,0x15,0x11,0x01,0x89,0xd0,0x1f,0x01,0x51,0x4c,0x01,0x32,0x09,0x0a,0xbc,0xfe,0xec,0x44,0x22,0x63,0x60,0x15,0x9e,0xfc,0xf6,0xaa,0x05,0x2f,0x85,0x69,0x3b,0xae,0xfe,0x9b,0x0f,0x16,0x01,0x95,0xef,0xde,0xb2,0xb5,0x4f,0x6d,0x01,0x15,0x5f,0x61,0xbc,0x1a,0x12,0x01,0xee,0x52,0x01,0x67,0x01,0x23,0x82,0xf1,0xf6,0x0e,0x0c,0xfe,0xd3,0xc5,0x9b,0xaf,0xfe,0x4d,0x6f,0x01,0x18,0x76,0x04,0x04,0x86,0xfe,0xa0,0xfe,0x05,0x1b,0x03,0x83,0x82,0x32,0x28,0x88,0x8a,0xfd,0xaa,0xdc,0xfe,0xca,0xfe,0xb9,0x05,0x01,0xbf,0x01,0x9a,0x00,0x00,0x00,0x01,0x00,0x64,0x05,0x0b,0x01,0x2c,0x07,0x41,0x00,0x09,0x00,0x00,0x00,0x17,0x03,0x06,0x07,0x26,0x35,0x03,0x36,0x33,0x01,0x23,0x09,0x0d,0x01,0x57,0x57,0x0c,0x14,0x52,0x07,0x3d,0x51,0xfe,0x8a,0x6a,0x01,0x01,0x6f,0x01,0x75,0x51,0x00,0x00,0x00,0x01,0x00,0x7d,0xfe,0x74,0x02,0x89,0x08,0x05,0x00,0x15,0x00,0x00,0x00,0x37,0x16,0x17,0x06,0x07,0x02,0x03,0x10,0x13,0x16,0x17,0x06,0x07,0x22,0x27,0x26,0x27,0x02,0x03,0x12,0x13,0x01,0xa6,0x7c,0x53,0x09,0x12,0x5c,0xc0,0x0d,0xc4,0x5b,0x27,0x01,0x4f,0x5a,0x30,0x3e,0x32,0xc1,0x01,0x0c,0xcb,0x08,0x01,0x04,0x15,0x65,0x62,0x8f,0xfe,0xd9,0xfe,0x17,0xfe,0x1d,0xfe,0x6a,0xa6,0x7c,0x73,0x08,0x3e,0x55,0x83,0x02,0x0a,0x01,0xdb,0x02,0x06,0x01,0xa3,0x00,0x01,0x00,0x51,0xfe,0x74,0x02,0x62,0x08,0x0a,0x00,0x15,0x00,0x00,0x12,0x27,0x34,0x37,0x16,0x17,0x12,0x13,0x02,0x03,0x06,0x07,0x06,0x07,0x22,0x27,0x36,0x37,0x12,0x13,0x02,0x03,0x81,0x1a,0x62,0x5b,0x4d,0xf0,0x01,0x01,0xb4,0x46,0x44,0x2e,0x44,0x59,0x07,0x0a,0x66,0xda,0x02,0x0a,0xb5,0x07,0x0e,0x7f,0x73,0x0a,0x0a,0xab,0xfe,0x5f,0xfd,0xa6,0xfe,0x1e,0xfe,0x35,0xaf,0x4d,0x35,0x08,0x6b,0x55,0x8a,0x01,0xbf,0x01,0xf8,0x01,0xce,0x01,0x50,0x00,0x00,0x01,0x00,0x4c,0x03,0xe6,0x02,0xe1,0x06,0xf3,0x00,0x27,0x00,0x00,0x01,0x26,0x35,0x36,0x33,0x32,0x17,0x14,0x07,0x36,0x37,0x16,0x15,0x06,0x07,0x16,0x17,0x06,0x07,0x26,0x27,0x16,0x15,0x06,0x07,0x26,0x27,0x36,0x37,0x06,0x07,0x26,0x27,0x36,0x37,0x26,0x27,0x36,0x37,0x16,0x01,0x64,0x1b,0x1c,0x30,0x30,0x1d,0x18,0x74,0x74,0x2c,0x21,0xab,0xc8,0x07,0x07,0x2c,0x50,0x88,0x12,0x09,0x40,0x49,0x09,0x01,0x12,0x7b,0x43,0x45,0x04,0x05,0xc7,0xbf,0x1a,0x01,0x3a,0x57,0x05,0xd9,0x84,0x4f,0x47,0x48,0x47,0x90,0xae,0x02,0x0d,0x3f,0x6c,0x50,0x53,0x5c,0x33,0x0e,0x08,0x76,0x7e,0x5b,0x48,0x03,0x0f,0x55,0x41,0x83,0x75,0x07,0x06,0x3d,0x43,0x69,0x4a,0x6e,0x3e,0x10,0x01,0x00,0x00,0x00,0x01,0x00,0xc0,0x00,0xc7,0x03,0xf3,0x03,0xed,0x00,0x17,0x00,0x00,0x01,0x33,0x16,0x17,0x06,0x07,0x23,0x15,0x06,0x07,0x26,0x3d,0x01,0x23,0x26,0x27,0x36,0x3b,0x01,0x35,0x36,0x37,0x16,0x17,0x02,0xc7,0x9b,0x84,0x0d,0x07,0x82,0xa2,0x06,0x68,0x5c,0xaf,0x8b,0x04,0x08,0x89,0xac,0x01,0x5d,0x60,0x0c,0x02,0xc9,0x01,0x5d,0x60,0x0c,0xab,0x89,0x04,0x08,0x86,0xa9,0x06,0x68,0x5c,0x97,0x81,0x0d,0x07,0x80,0x00,0x00,0x01,0x00,0x9e,0xfe,0xf1,0x01,0x66,0x00,0xe1,0x00,0x09,0x00,0x00,0x24,0x17,0x03,0x06,0x07,0x26,0x35,0x03,0x36,0x33,0x01,0x5d,0x09,0x0d,0x01,0x57,0x57,0x0c,0x14,0x52,0xdd,0x51,0xfe,0xd0,0x6a,0x01,0x01,0x6f,0x01,0x2f,0x51,0x00,0x00,0x00,0x00,0x01,0x00,0x14,0x02,0x63,0x02,0xe4,0x03,0x2e,0x00,0x09,0x00,0x00,0x00,0x17,0x06,0x07,0x05,0x26,0x27,0x36,0x33,0x25,0x02,0xd8,0x0c,0x06,0x72,0xfe,0x26,0x7a,0x04,0x07,0x78,0x01,0xd2,0x03,0x2d,0x5d,0x60,0x0c,0x01,0x06,0x68,0x5c,0x01,0x00,0x00,0x01,0x00,0x9e,0xff,0xfe,0x01,0xa2,0x01,0x09,0x00,0x07,0x00,0x00,0x36,0x37,0x32,0x17,0x14,0x07,0x26,0x27,0x9f,0x76,0x83,0x0a,0x7b,0x7f,0x0a,0xff,0x0a,0x7f,0x89,0x03,0x01,0x7a,0x00,0x01,0xff,0xf7,0xff,0xe0,0x03,0x38,0x07,0x4f,0x00,0x0d,0x00,0x00,0x01,0x16,0x17,0x06,0x07,0x01,0x06,0x23,0x26,0x27,0x34,0x37,0x01,0x36,0x02,0xf5,0x42,0x01,0x06,0x1c,0xfd,0x80,0x1f,0x3a,0x40,0x06,0x25,0x02,0x80,0x13,0x07,0x4f,0x05,0x61,0x3c,0x36,0xf9,0xbe,0x55,0x04,0x44,0x2c,0x56,0x06,0x43,0x58,0x00,0x02,0x00,0x0d,0xff,0xf1,0x04,0x64,0x05,0xca,0x00,0x0b,0x00,0x15,0x00,0x00,0x01,0x17,0x04,0x13,0x17,0x02,0x05,0x27,0x24,0x03,0x27,0x12,0x13,0x12,0x05,0x20,0x13,0x27,0x02,0x25,0x04,0x03,0x02,0x38,0x44,0x01,0x92,0x50,0x06,0x22,0xfd,0xdb,0x43,0xfe,0x77,0x36,0x0e,0x0f,0xad,0x11,0x01,0x11,0x01,0x9e,0x24,0x05,0x34,0xfe,0xd7,0xfe,0xb4,0x3a,0x05,0xca,0x03,0x37,0xfd,0xf2,0x88,0xfd,0x0e,0x17,0x03,0x64,0x01,0xae,0x85,0x03,0x18,0xfc,0xee,0xfe,0x67,0x4a,0x02,0x33,0x6b,0x01,0xb4,0x12,0x15,0xfd,0xe6,0x00,0x00,0x01,0x00,0xa9,0x00,0x00,0x03,0x13,0x05,0xc1,0x00,0x12,0x00,0x00,0x00,0x17,0x02,0x03,0x06,0x23,0x26,0x27,0x12,0x11,0x06,0x07,0x26,0x27,0x34,0x3f,0x01,0x36,0x33,0x02,0xfe,0x15,0x05,0x15,0x09,0x5e,0x57,0x11,0x23,0xe3,0x66,0x48,0x13,0x2f,0xe4,0x8b,0x59,0x05,0xb7,0x40,0xfe,0x08,0xfc,0xc4,0x43,0x03,0x3e,0x03,0x3d,0x01,0x51,0xf9,0x0c,0x07,0x3d,0x48,0x25,0xba,0x8c,0x00,0x00,0x00,0x00,0x01,0x00,0x28,0xff,0xf6,0x04,0x48,0x05,0xb7,0x00,0x20,0x00,0x00,0x01,0x04,0x13,0x14,0x02,0x05,0x25,0x32,0x16,0x17,0x14,0x23,0x26,0x27,0x04,0x07,0x26,0x35,0x36,0x25,0x24,0x11,0x02,0x25,0x04,0x03,0x06,0x23,0x22,0x27,0x37,0x12,0x25,0x02,0x5c,0x01,0x9b,0x35,0xfa,0xfe,0x7c,0x01,0x0e,0x91,0xf5,0x06,0x6f,0x44,0xd5,0xfe,0x69,0x6f,0x67,0x01,0x01,0x83,0x01,0x92,0x18,0xfe,0xed,0xfe,0xea,0x3a,0x0a,0x5d,0x5e,0x01,0x02,0x44,0x01,0x9a,0x05,0xb7,0x2b,0xfe,0x62,0xe5,0xfe,0xb2,0xe9,0x12,0x30,0x62,0x57,0x19,0x0c,0x11,0x19,0x0a,0x61,0x7e,0xfc,0xe7,0x01,0x1f,0x01,0x09,0x19,0x0a,0xfe,0xf8,0x74,0x6a,0x1f,0x01,0x83,0x2e,0x00,0x00,0x00,0x01,0x00,0x20,0xff,0xf7,0x04,0x57,0x05,0xc5,0x00,0x27,0x00,0x00,0x01,0x04,0x1f,0x01,0x06,0x07,0x04,0x13,0x02,0x05,0x24,0x03,0x36,0x33,0x32,0x12,0x17,0x24,0x37,0x02,0x25,0x06,0x07,0x26,0x35,0x36,0x37,0x36,0x35,0x26,0x27,0x04,0x07,0x14,0x07,0x26,0x27,0x37,0x12,0x25,0x02,0x69,0x01,0x1c,0x3d,0x0a,0x08,0x87,0x01,0x15,0x05,0x33,0xfe,0x16,0xfe,0x00,0x1a,0x0e,0x54,0x42,0x62,0xfb,0x01,0x49,0x23,0x13,0xfe,0xfd,0x5e,0x6c,0x61,0x0b,0xd0,0xcb,0x11,0x86,0xfe,0xbd,0x32,0x5e,0x4c,0x09,0x01,0x49,0x01,0x8f,0x05,0xc5,0x18,0xee,0x3c,0x9e,0x74,0x55,0xfe,0xab,0xfe,0x5d,0x2d,0x04,0x01,0x98,0x47,0xfe,0xfe,0x14,0x0e,0xfb,0x01,0x14,0x0e,0x07,0x07,0x14,0x54,0x5d,0x19,0x18,0xc1,0x72,0x07,0x07,0xc7,0x46,0x0a,0x14,0x55,0x32,0x01,0x20,0x15,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0xff,0xf6,0x04,0x6a,0x05,0xc8,0x00,0x17,0x00,0x1d,0x00,0x00,0x01,0x32,0x17,0x02,0x03,0x37,0x16,0x17,0x06,0x23,0x27,0x13,0x06,0x23,0x26,0x27,0x37,0x04,0x05,0x26,0x3d,0x01,0x12,0x00,0x17,0x00,0x03,0x36,0x37,0x12,0x02,0xe4,0x80,0x14,0x03,0x23,0xa4,0x60,0x14,0x0b,0x49,0xc4,0x05,0x10,0x56,0x54,0x0a,0x09,0xfe,0xe4,0xfe,0xe3,0x63,0x25,0x02,0x74,0x2b,0xfe,0x18,0x09,0xd4,0xf8,0x22,0x05,0xc8,0x6b,0xfe,0x7b,0xfe,0x1f,0x0b,0x09,0x5e,0x6c,0x08,0xff,0x00,0x41,0x07,0x5d,0xd4,0x02,0x35,0x0f,0x88,0x2a,0x01,0x2d,0x02,0xe3,0xed,0xfe,0x00,0xfe,0xe9,0x2d,0x02,0x01,0xf1,0x00,0x00,0x01,0x00,0x35,0xff,0xf2,0x04,0x46,0x05,0xc1,0x00,0x2c,0x00,0x00,0x01,0x36,0x37,0x32,0x17,0x0e,0x01,0x07,0x25,0x06,0x07,0x17,0x3e,0x01,0x37,0x16,0x12,0x1d,0x01,0x02,0x05,0x07,0x22,0x00,0x35,0x36,0x37,0x32,0x17,0x16,0x17,0x36,0x13,0x37,0x02,0x27,0x0e,0x01,0x07,0x22,0x27,0x12,0x3f,0x01,0x16,0x02,0x52,0x8f,0x7a,0x58,0x08,0x01,0x8b,0xd5,0xfe,0xf9,0x56,0x02,0x0d,0x52,0xc7,0x87,0xe0,0xbe,0x28,0xfe,0x97,0x87,0xd2,0xfe,0xd9,0x07,0x4a,0x49,0x35,0x6b,0xe9,0xff,0x2f,0x04,0x0f,0xe9,0x71,0xe8,0x5c,0x8a,0x14,0x22,0x93,0x21,0x6d,0x05,0xa5,0x08,0x14,0x52,0x51,0x2c,0x06,0x05,0x8d,0x6f,0x0f,0x0c,0x37,0x0a,0x06,0xfe,0xdc,0xba,0x4d,0xfe,0x23,0x2d,0x06,0x01,0x03,0x76,0x41,0x0a,0x59,0xa6,0x01,0x0a,0x01,0x2c,0x69,0x01,0x0c,0x0f,0x0d,0x3f,0x04,0xae,0x01,0x3a,0xaa,0x07,0x10,0x00,0x00,0x00,0x00,0x02,0x00,0x0a,0x00,0x00,0x04,0x66,0x05,0xb8,0x00,0x19,0x00,0x23,0x00,0x00,0x01,0x17,0x16,0x17,0x06,0x07,0x2e,0x01,0x27,0x06,0x02,0x07,0x36,0x37,0x33,0x04,0x13,0x07,0x02,0x05,0x24,0x03,0x35,0x10,0x37,0x36,0x03,0x15,0x12,0x05,0x33,0x24,0x13,0x10,0x25,0x04,0x02,0x40,0x3c,0xf7,0x11,0x0c,0x55,0x5a,0x41,0x41,0x94,0xdc,0x0e,0x8b,0xf2,0x21,0x01,0xd5,0x2a,0x01,0x1f,0xfe,0x1e,0xfd,0xb8,0x12,0x96,0xcb,0x9d,0x22,0x01,0x53,0x26,0x01,0x36,0x0a,0xfe,0xc3,0xfe,0xbb,0x05,0xb8,0x01,0x20,0x74,0x52,0x06,0x0a,0x24,0x10,0x0e,0xfe,0xdf,0x9a,0xa8,0x12,0x1f,0xfe,0x70,0x6b,0xfe,0x76,0x56,0x06,0x02,0x55,0x4a,0x01,0x39,0xdd,0xfc,0xfc,0x6c,0x37,0xfe,0xdd,0x0a,0x4c,0x01,0x0f,0x01,0x05,0x26,0x25,0x00,0x01,0x00,0x1a,0xff,0xfb,0x04,0x4d,0x05,0xc0,0x00,0x19,0x00,0x00,0x01,0x16,0x17,0x14,0x07,0x00,0x03,0x15,0x06,0x23,0x22,0x35,0x37,0x12,0x25,0x06,0x07,0x27,0x26,0x27,0x34,0x37,0x16,0x17,0x36,0x24,0x03,0xc4,0x7f,0x0a,0x3b,0xfe,0x42,0x10,0x12,0x5a,0x69,0x01,0x4e,0x01,0x3a,0x77,0xe7,0x91,0xe7,0x08,0x66,0xcc,0x70,0x5e,0x01,0x39,0x05,0xc0,0x0a,0x53,0x3f,0x28,0xfe,0xc5,0xfd,0xa6,0xf0,0x7c,0x85,0xf0,0x02,0x91,0xfc,0x2b,0x0d,0x0d,0x14,0x63,0x5c,0x0d,0x21,0x04,0x06,0x2d,0x00,0x00,0x00,0x03,0x00,0x11,0xff,0xef,0x04,0x61,0x05,0xd6,0x00,0x15,0x00,0x1d,0x00,0x27,0x00,0x00,0x01,0x33,0x04,0x13,0x17,0x06,0x07,0x04,0x13,0x15,0x02,0x05,0x27,0x24,0x03,0x35,0x12,0x37,0x26,0x27,0x37,0x12,0x13,0x16,0x17,0x36,0x37,0x26,0x27,0x06,0x02,0x07,0x16,0x05,0x37,0x24,0x13,0x26,0x25,0x07,0x02,0x2d,0x2a,0x01,0x23,0x3b,0x01,0x09,0x7b,0x01,0x16,0x19,0x25,0xfe,0x13,0x60,0xfe,0x4d,0x2b,0x10,0xcd,0x67,0x0a,0x04,0x2d,0x92,0x05,0xbd,0xe7,0x11,0x1a,0x8c,0xfb,0x87,0x07,0x01,0x01,0x46,0x34,0x01,0x51,0x06,0x1b,0xfe,0x9d,0x51,0x05,0xd6,0x01,0xfe,0xff,0x2d,0xd0,0x55,0x3e,0xfe,0xeb,0x37,0xfe,0x11,0x1a,0x02,0x16,0x01,0x6d,0x3c,0x01,0x17,0x8a,0x66,0x98,0x29,0x01,0x33,0xfe,0xb8,0xae,0x04,0x29,0xc1,0x8c,0x08,0x0c,0xfd,0x6a,0xf5,0xc9,0x2a,0x01,0x32,0x01,0x34,0xd4,0x11,0x0d,0x00,0x00,0x00,0x00,0x02,0x00,0x21,0xff,0xfe,0x04,0x53,0x05,0xc1,0x00,0x13,0x00,0x1e,0x00,0x00,0x01,0x04,0x13,0x02,0x05,0x27,0x26,0x35,0x34,0x24,0x00,0x13,0x27,0x02,0x05,0x24,0x03,0x10,0x37,0x36,0x03,0x16,0x17,0x20,0x13,0x27,0x2e,0x01,0x23,0x07,0x06,0x02,0x08,0x02,0x26,0x25,0x20,0xfd,0x3b,0x4d,0x42,0x01,0xa3,0x01,0x28,0x04,0x0f,0x57,0xfe,0x6c,0xfe,0x97,0x2a,0xb2,0x7d,0x84,0x10,0xc2,0x01,0x5c,0x34,0x06,0x11,0x9b,0x8c,0x2e,0xf6,0x05,0xc1,0x27,0xfd,0x21,0xfd,0x53,0x10,0x02,0x13,0x35,0x75,0x01,0x01,0x04,0x01,0x13,0x5f,0xfe,0xa1,0x0a,0x17,0x01,0x83,0x01,0x38,0xb2,0x72,0xfd,0xa6,0xd5,0x14,0x01,0x76,0x59,0x48,0x80,0x0b,0x46,0x00,0x00,0x00,0x02,0x00,0x9e,0xff,0xfe,0x01,0xa2,0x04,0x87,0x00,0x07,0x00,0x0f,0x00,0x00,0x36,0x37,0x32,0x17,0x14,0x07,0x26,0x27,0x12,0x37,0x32,0x17,0x14,0x07,0x26,0x27,0x9f,0x76,0x83,0x0a,0x7b,0x7f,0x0a,0x01,0x76,0x83,0x0a,0x7b,0x7f,0x0a,0xff,0x0a,0x7f,0x89,0x03,0x01,0x7a,0x04,0x04,0x0a,0x7f,0x89,0x03,0x01,0x7a,0x00,0x00,0x00,0x00,0x02,0x00,0x9e,0xff,0x08,0x01,0xa2,0x04,0x87,0x00,0x07,0x00,0x11,0x00,0x00,0x12,0x37,0x32,0x17,0x14,0x07,0x26,0x27,0x12,0x17,0x03,0x06,0x07,0x26,0x35,0x03,0x36,0x33,0x9f,0x76,0x83,0x0a,0x7b,0x7f,0x0a,0xdc,0x09,0x0d,0x01,0x57,0x57,0x0c,0x14,0x52,0x04,0x7d,0x0a,0x7f,0x89,0x03,0x01,0x7a,0xfc,0xfd,0x51,0xfe,0xd0,0x6a,0x01,0x01,0x6f,0x01,0x2f,0x51,0x00,0x00,0x00,0x01,0x00,0xc9,0x00,0x91,0x04,0x07,0x04,0x84,0x00,0x13,0x00,0x00,0x09,0x01,0x16,0x17,0x14,0x07,0x22,0x27,0x01,0x26,0x27,0x36,0x37,0x01,0x36,0x33,0x16,0x15,0x06,0x07,0x01,0xf6,0x01,0xc1,0x4e,0x02,0x46,0x3c,0x36,0xfd,0xd8,0x5b,0x03,0x03,0x5b,0x02,0x28,0x36,0x3c,0x46,0x02,0x4e,0x02,0x8b,0xfe,0xd6,0x27,0x4a,0x43,0x1c,0x20,0x01,0x56,0x1f,0x63,0x66,0x1f,0x01,0x56,0x20,0x1c,0x43,0x4a,0x27,0x00,0x00,0x00,0x02,0x00,0xc0,0x01,0x69,0x04,0x12,0x03,0x8b,0x00,0x09,0x00,0x13,0x00,0x00,0x00,0x17,0x06,0x07,0x05,0x26,0x27,0x36,0x33,0x25,0x12,0x17,0x06,0x07,0x21,0x26,0x27,0x36,0x33,0x25,0x04,0x04,0x0e,0x07,0x6c,0xfd,0x9b,0x75,0x05,0x08,0x73,0x02,0x5c,0x6d,0x0e,0x07,0x6c,0xfd,0x9b,0x75,0x05,0x08,0x73,0x02,0x5c,0x02,0x38,0x5e,0x62,0x0e,0x01,0x07,0x6b,0x5d,0x01,0x01,0x51,0x5f,0x62,0x0d,0x05,0x6b,0x5e,0x01,0x00,0x01,0x00,0xc9,0x00,0x91,0x04,0x07,0x04,0x84,0x00,0x13,0x00,0x00,0x01,0x26,0x27,0x34,0x37,0x32,0x17,0x01,0x16,0x17,0x06,0x07,0x01,0x06,0x23,0x26,0x35,0x36,0x37,0x01,0x01,0x19,0x4e,0x02,0x46,0x3c,0x36,0x02,0x28,0x5b,0x03,0x03,0x5b,0xfd,0xd8,0x36,0x3c,0x46,0x02,0x4e,0x01,0xc1,0x03,0xb4,0x27,0x4a,0x43,0x1c,0x20,0xfe,0xaa,0x1f,0x66,0x63,0x1f,0xfe,0xaa,0x20,0x1c,0x43,0x4a,0x27,0x01,0x2a,0x00,0x00,0x00,0x02,0x00,0xbc,0xff,0xff,0x03,0xca,0x07,0x4f,0x00,0x19,0x00,0x21,0x00,0x00,0x01,0x37,0x04,0x13,0x10,0x05,0x06,0x0f,0x01,0x06,0x23,0x26,0x35,0x34,0x37,0x36,0x35,0x34,0x27,0x0e,0x01,0x07,0x26,0x27,0x37,0x36,0x12,0x33,0x16,0x17,0x06,0x07,0x26,0x27,0x01,0xcf,0x79,0x01,0x74,0x0e,0xfe,0xb4,0x59,0x0a,0x01,0x15,0x61,0x63,0xbb,0xf9,0xe4,0x55,0x54,0x45,0x4c,0x1b,0x04,0x22,0x56,0x7b,0x63,0x1b,0x04,0x75,0x90,0x01,0x07,0x43,0x0c,0x14,0xfe,0x9a,0xfe,0xf5,0xe1,0x40,0x81,0xba,0x57,0x11,0xd7,0xf8,0x92,0x9e,0x9d,0xaa,0x09,0x0d,0x50,0x05,0x06,0x5d,0x2a,0x6b,0xfa,0x02,0x11,0x61,0x91,0x0d,0x19,0x8a,0x00,0x00,0x00,0x02,0x00,0x40,0x00,0x1e,0x06,0x10,0x05,0xa4,0x00,0x08,0x00,0x3d,0x00,0x00,0x01,0x14,0x17,0x36,0x13,0x27,0x37,0x06,0x08,0x01,0x05,0x26,0x2f,0x01,0x02,0x05,0x20,0x03,0x35,0x12,0x25,0x32,0x15,0x14,0x07,0x17,0x07,0x12,0x17,0x36,0x13,0x02,0x25,0x23,0x04,0x00,0x0f,0x01,0x12,0x05,0x36,0x37,0x17,0x16,0x17,0x16,0x17,0x06,0x07,0x26,0x27,0x05,0x24,0x03,0x27,0x12,0x00,0x25,0x37,0x04,0x13,0x17,0x01,0xcc,0x7e,0xe6,0xbd,0x04,0x04,0xe1,0xfe,0xd0,0x04,0x16,0xfe,0xfc,0xad,0x17,0x16,0xab,0xfe,0xf8,0xfe,0xe7,0x0b,0x3b,0x02,0x8c,0x91,0x0f,0x0f,0x02,0x09,0x56,0x7e,0x04,0x56,0xfe,0xf9,0x7e,0xfe,0xc9,0xfe,0x89,0x07,0x03,0x3a,0x01,0x3a,0xf1,0x77,0x66,0x95,0x98,0x2d,0x09,0x0e,0x54,0x8c,0x87,0xfe,0x43,0xfe,0x33,0x42,0x05,0x0d,0x01,0xd7,0x01,0x9b,0x4f,0x01,0x93,0x63,0x0c,0x02,0x64,0x94,0x16,0x05,0x01,0x54,0xc2,0x61,0x0b,0xfe,0xfc,0xfd,0xf8,0x08,0x0e,0xa9,0x82,0xfe,0xd4,0x04,0x01,0x20,0x47,0x02,0x1e,0x2b,0x4b,0x1f,0x17,0x81,0xcf,0xfe,0xb8,0x0b,0x38,0x01,0x50,0x01,0xd6,0x0c,0x10,0xfe,0x5c,0xd8,0x60,0xfe,0xb8,0x19,0x0a,0x05,0x04,0x07,0x16,0x0d,0x34,0x51,0x07,0x1e,0x0a,0x08,0x0d,0x01,0xb9,0x61,0x01,0x53,0x01,0xe0,0x0a,0x02,0x1c,0xfe,0x0a,0xa5,0x00,0x00,0x02,0x00,0x45,0xff,0xfc,0x06,0x62,0x07,0x4a,0x00,0x15,0x00,0x1c,0x00,0x00,0x01,0x04,0x00,0x13,0x11,0x14,0x23,0x22,0x35,0x11,0x21,0x11,0x14,0x07,0x26,0x27,0x11,0x36,0x37,0x16,0x15,0x12,0x03,0x21,0x26,0x00,0x21,0x20,0x00,0x03,0x81,0x01,0x77,0x01,0x67,0x03,0x5d,0x6e,0xfb,0x7d,0x67,0x67,0x01,0x04,0x60,0x6a,0xdc,0xbc,0x04,0x58,0x01,0xfe,0xff,0xfe,0xf3,0xfe,0xfb,0xfe,0xbc,0x07,0x4a,0x06,0xfe,0x13,0xfe,0x6a,0xfc,0x9f,0x64,0x62,0x02,0xff,0xfd,0x0d,0x6c,0x01,0x02,0x6b,0x05,0xb8,0x6c,0x01,0x01,0x90,0x01,0x4c,0xfc,0xd5,0xce,0x01,0x91,0xfe,0x64,0x00,0x00,0x00,0x00,0x02,0x00,0x57,0xff,0xf0,0x06,0x2f,0x07,0x65,0x00,0x25,0x00,0x2f,0x00,0x00,0x13,0x32,0x17,0x36,0x25,0x04,0x00,0x13,0x15,0x02,0x05,0x16,0x15,0x14,0x04,0x21,0x26,0x27,0x26,0x35,0x36,0x33,0x16,0x17,0x20,0x24,0x35,0x34,0x24,0x27,0x21,0x11,0x06,0x07,0x22,0x35,0x11,0x34,0x05,0x22,0x07,0x11,0x21,0x2c,0x01,0x37,0x26,0x00,0xb7,0x49,0x11,0x4e,0x01,0x01,0x01,0x81,0x02,0x3d,0x11,0x0b,0xfe,0xc3,0xcd,0xfe,0x5f,0xfe,0x6b,0x70,0x6d,0x55,0x02,0x65,0x65,0x6e,0x01,0x2a,0x01,0x3e,0xfe,0xe3,0xe4,0xfe,0x3b,0x21,0x51,0x5f,0x01,0xbf,0xe0,0x0e,0x01,0x75,0x01,0xa7,0x01,0x18,0x01,0x01,0xfe,0x2a,0x07,0x65,0x4d,0x2b,0x03,0x01,0xfe,0x74,0xfe,0xd0,0x31,0xfe,0xe3,0xb4,0x42,0xd8,0xc1,0xbc,0x07,0x08,0x1f,0x46,0x59,0x0c,0x02,0x63,0x62,0x67,0x48,0x03,0xfe,0x2a,0x50,0x0e,0x65,0x06,0xbc,0x4e,0xe3,0x2c,0xfc,0x9d,0x06,0xf4,0x9d,0xc4,0x01,0x33,0x00,0x01,0x00,0x3c,0xff,0xeb,0x05,0xe5,0x07,0x53,0x00,0x1a,0x00,0x00,0x01,0x32,0x04,0x17,0x06,0x07,0x22,0x26,0x23,0x06,0x00,0x03,0x12,0x00,0x33,0x20,0x36,0x33,0x16,0x17,0x14,0x04,0x05,0x24,0x03,0x12,0x00,0x03,0xb1,0xda,0x01,0x51,0x01,0x09,0x58,0x46,0xb7,0xd0,0xfa,0xfe,0x66,0x01,0x01,0x01,0x72,0xed,0x01,0x01,0xc2,0x52,0x55,0x01,0xfe,0x8d,0xff,0x00,0xfc,0xd0,0x06,0x02,0x02,0x18,0x07,0x53,0xbb,0x60,0x61,0x01,0x9d,0x01,0xfe,0x16,0xfe,0xbc,0xfe,0x9f,0xfe,0xe9,0x33,0x0f,0x5a,0x70,0x33,0x08,0x0d,0x03,0x55,0x01,0xbc,0x02,0x45,0x00,0x00,0x00,0x00,0x01,0x00,0x34,0xff,0xf2,0x06,0x11,0x07,0x65,0x00,0x1f,0x00,0x00,0x25,0x06,0x07,0x22,0x35,0x11,0x34,0x37,0x32,0x17,0x36,0x37,0x04,0x00,0x13,0x10,0x00,0x05,0x27,0x26,0x35,0x36,0x37,0x17,0x24,0x00,0x11,0x02,0x00,0x25,0x22,0x07,0x01,0x00,0x0d,0x5b,0x64,0x65,0x53,0x11,0x4e,0xf7,0x01,0x95,0x02,0x29,0x11,0xfd,0xf7,0xfe,0x62,0xfb,0x55,0x02,0x65,0xe7,0x01,0x43,0x01,0x94,0x01,0xfe,0x5c,0xfe,0x90,0xd6,0x54,0x50,0x50,0x0e,0x65,0x06,0xbc,0x4e,0x04,0x4d,0x2b,0x03,0x01,0xfe,0x74,0xfe,0x62,0xfe,0x81,0xfd,0x5f,0x02,0x06,0x1f,0x50,0x54,0x0a,0x05,0x15,0x01,0xf4,0x01,0x48,0x01,0x28,0x01,0x33,0x01,0x2c,0x00,0x00,0x01,0x00,0x38,0xff,0xfe,0x05,0x91,0x07,0x45,0x00,0x1a,0x00,0x00,0x01,0x16,0x15,0x06,0x07,0x21,0x03,0x21,0x16,0x15,0x06,0x07,0x21,0x11,0x21,0x16,0x15,0x06,0x07,0x21,0x26,0x27,0x11,0x26,0x27,0x34,0x37,0x04,0xef,0x5d,0x02,0x68,0xfc,0x47,0x01,0x03,0x5e,0x67,0x01,0x69,0xfc,0xa9,0x04,0x01,0x64,0x11,0x4e,0xfb,0x82,0x52,0x01,0x28,0x01,0x6a,0x07,0x45,0x09,0x58,0x66,0x03,0xfc,0x76,0x01,0x6b,0x5f,0x07,0xfe,0xa7,0x09,0x5b,0x57,0x0d,0x11,0x7f,0x05,0xf4,0x10,0x56,0x54,0x09,0x00,0x00,0x00,0x01,0x00,0x35,0xff,0xfd,0x04,0xa8,0x07,0x4c,0x00,0x16,0x00,0x00,0x01,0x16,0x15,0x06,0x07,0x21,0x11,0x21,0x16,0x15,0x06,0x07,0x21,0x13,0x06,0x07,0x26,0x27,0x11,0x26,0x27,0x34,0x37,0x04,0x4b,0x5d,0x02,0x68,0xfc,0xf0,0x02,0xa0,0x5d,0x01,0x5f,0xfd,0x65,0x01,0x06,0x69,0x63,0x01,0x28,0x01,0x6a,0x07,0x4c,0x09,0x58,0x68,0x03,0xfd,0x9d,0x0e,0x5f,0x61,0x07,0xfd,0x21,0x6b,0x01,0x01,0x72,0x06,0x19,0x10,0x56,0x54,0x09,0x00,0x00,0x01,0x00,0x1e,0xff,0xeb,0x07,0x19,0x07,0x53,0x00,0x28,0x00,0x00,0x01,0x13,0x21,0x22,0x27,0x36,0x37,0x21,0x16,0x17,0x14,0x07,0x27,0x11,0x06,0x23,0x26,0x2f,0x01,0x04,0x07,0x24,0x03,0x12,0x00,0x25,0x32,0x04,0x17,0x06,0x07,0x22,0x26,0x23,0x06,0x00,0x03,0x12,0x00,0x33,0x32,0x05,0x80,0x01,0xfe,0x9b,0x64,0x03,0x02,0x5f,0x02,0xae,0x53,0x02,0x51,0x7c,0x0f,0x5a,0x48,0x0f,0x03,0xfe,0xb7,0xf6,0xfc,0xda,0x06,0x02,0x02,0x18,0x01,0x5b,0xda,0x01,0x51,0x01,0x09,0x58,0x46,0xb7,0xd0,0xfa,0xfe,0x5c,0x01,0x01,0x01,0x68,0xf7,0xf7,0x01,0x81,0x01,0x0d,0x5d,0x66,0x03,0x0e,0x61,0x54,0x05,0x01,0xfd,0xb6,0x4b,0x04,0x44,0x4e,0x9b,0x08,0x0d,0x03,0x55,0x01,0xbc,0x02,0x45,0x05,0xbb,0x60,0x61,0x01,0x9d,0x01,0xfe,0x16,0xfe,0xbc,0xfe,0x9f,0xfe,0xe9,0x00,0x00,0x00,0x01,0x00,0x1d,0xff,0xf5,0x06,0xb7,0x07,0x47,0x00,0x22,0x00,0x00,0x01,0x13,0x36,0x37,0x32,0x17,0x11,0x16,0x15,0x06,0x07,0x11,0x06,0x23,0x26,0x27,0x03,0x21,0x11,0x06,0x23,0x26,0x27,0x11,0x26,0x35,0x36,0x37,0x11,0x36,0x37,0x32,0x17,0x11,0x21,0x05,0x8b,0x01,0x01,0x6d,0x6b,0x01,0x51,0x01,0x50,0x01,0x6b,0x6d,0x01,0x01,0xfb,0xc7,0x01,0x6b,0x6d,0x01,0x5b,0x02,0x59,0x01,0x6d,0x6b,0x01,0x04,0x39,0x03,0x6f,0x03,0x4d,0x8a,0x01,0x8a,0xfc,0x35,0x10,0x58,0x59,0x07,0xfe,0x50,0x85,0x01,0x85,0x01,0xab,0xfe,0x5a,0x81,0x01,0x81,0x01,0xaa,0x08,0x55,0x56,0x13,0x03,0xc8,0x8d,0x01,0x8c,0xfc,0x3b,0x00,0x00,0x00,0x00,0x01,0x00,0x33,0xff,0xfc,0x02,0x8f,0x07,0x44,0x00,0x17,0x00,0x00,0x13,0x23,0x22,0x35,0x34,0x33,0x21,0x32,0x15,0x14,0x2b,0x01,0x11,0x33,0x32,0x15,0x14,0x23,0x21,0x22,0x35,0x34,0x3b,0x01,0xf2,0x53,0x6c,0x71,0x01,0x7a,0x71,0x6c,0x5c,0x5c,0x6c,0x71,0xfe,0x86,0x71,0x6c,0x53,0x06,0x71,0x76,0x5d,0x5d,0x76,0xfa,0x5e,0x76,0x5d,0x5d,0x76,0x00,0x00,0x01,0x00,0x51,0xff,0xf6,0x06,0x9f,0x07,0x5b,0x00,0x21,0x00,0x00,0x01,0x05,0x26,0x35,0x36,0x33,0x21,0x34,0x37,0x32,0x17,0x33,0x32,0x15,0x06,0x2b,0x01,0x16,0x11,0x02,0x00,0x05,0x22,0x24,0x27,0x36,0x37,0x32,0x16,0x33,0x24,0x00,0x13,0x10,0x04,0xbb,0xfc,0x34,0x7f,0x06,0x78,0x03,0xa8,0x66,0x6e,0x01,0xb1,0x83,0x0a,0x6f,0x97,0x27,0x02,0xfe,0x42,0xfe,0x87,0xda,0xfe,0xaf,0x01,0x09,0x58,0x46,0xc2,0xd0,0x01,0x18,0x01,0x3f,0x01,0x06,0x10,0x01,0x01,0x69,0x6c,0x71,0x05,0x76,0x64,0x70,0xe4,0xfe,0xcf,0xfd,0xea,0xfe,0x15,0x05,0xbb,0x60,0x61,0x01,0xaa,0x01,0x01,0x89,0x01,0xb2,0x01,0x2c,0x00,0x01,0xff,0xf9,0xff,0xf8,0x06,0x46,0x07,0x53,0x00,0x24,0x00,0x00,0x01,0x00,0x01,0x36,0x37,0x16,0x15,0x14,0x07,0x00,0x01,0x04,0x01,0x16,0x15,0x06,0x07,0x26,0x27,0x00,0x25,0x11,0x14,0x23,0x22,0x27,0x33,0x03,0x26,0x27,0x34,0x37,0x03,0x34,0x33,0x32,0x15,0x01,0x1a,0x02,0xfe,0x01,0x64,0x1c,0x58,0x56,0x38,0xfe,0x7e,0xfc,0x98,0x02,0xf2,0x01,0xd6,0x4d,0x04,0x5f,0x3a,0x2f,0xfe,0x4c,0xfd,0x61,0x65,0x71,0x01,0x03,0x01,0x49,0x03,0x4c,0x01,0x71,0x65,0x03,0x5e,0x01,0x54,0x02,0x44,0x53,0x01,0x06,0x49,0x3f,0x61,0xfd,0x7d,0xfe,0xae,0x70,0xfe,0xc9,0x3f,0x52,0x4e,0x04,0x07,0x1d,0x01,0x27,0x6d,0xfe,0xa1,0x5d,0x5d,0x01,0xae,0x15,0x56,0x4f,0x25,0x04,0x07,0x6a,0x71,0x00,0x00,0x01,0x00,0x43,0xff,0xfa,0x05,0xa8,0x07,0x50,0x00,0x12,0x00,0x00,0x13,0x16,0x15,0x11,0x20,0x25,0x36,0x37,0x16,0x17,0x14,0x07,0x04,0x0d,0x01,0x26,0x27,0x03,0x36,0xaf,0x6d,0x02,0x7e,0x01,0x0f,0x4d,0x54,0x5a,0x04,0x7c,0xfe,0xe0,0xfe,0x9a,0xfe,0x67,0xc4,0x05,0x01,0x03,0x07,0x50,0x01,0x70,0xf9,0xf2,0x53,0x1f,0x0c,0x04,0x63,0x63,0x26,0x4c,0x16,0x03,0x09,0xbc,0x06,0x1d,0x73,0x00,0x00,0x01,0x00,0x3d,0x00,0x05,0x08,0xf0,0x07,0x43,0x00,0x1b,0x00,0x00,0x00,0x27,0x00,0x25,0x11,0x06,0x07,0x22,0x27,0x11,0x36,0x37,0x04,0x01,0x00,0x25,0x16,0x17,0x11,0x06,0x23,0x26,0x35,0x11,0x04,0x01,0x06,0x07,0x04,0x42,0x09,0xfe,0x99,0xfe,0x47,0x01,0x6d,0x61,0x0d,0x06,0x5d,0x02,0xb8,0x01,0x3f,0x01,0x3e,0x02,0xb8,0x5b,0x08,0x0d,0x61,0x70,0xfe,0x49,0xfe,0x99,0x09,0x56,0x01,0x2c,0x49,0x04,0x97,0x3d,0xfa,0x3f,0x82,0x01,0x86,0x06,0x45,0x6b,0x08,0x2f,0xfb,0xef,0x04,0x11,0x2f,0x08,0x6b,0xf9,0xbb,0x86,0x01,0x82,0x05,0xc1,0x3d,0xfb,0x69,0x49,0x05,0x00,0x00,0x00,0x00,0x01,0x00,0x3d,0xff,0xf7,0x06,0xc8,0x07,0x43,0x00,0x16,0x00,0x00,0x13,0x04,0x01,0x11,0x36,0x37,0x16,0x15,0x11,0x06,0x23,0x26,0x2f,0x01,0x00,0x25,0x11,0x14,0x07,0x22,0x27,0x11,0x36,0xa0,0x03,0xa3,0x01,0xaa,0x02,0x5b,0x7e,0x08,0x63,0x62,0x09,0x01,0xfe,0x35,0xfc,0xf0,0x6b,0x61,0x0d,0x06,0x07,0x43,0x57,0xfc,0x47,0x03,0x91,0x60,0x18,0x01,0x79,0xf9,0x9e,0x69,0x0a,0x57,0xcd,0x04,0xbf,0x6f,0xfa,0x35,0x82,0x01,0x86,0x06,0x45,0x6b,0x00,0x00,0x00,0x02,0x00,0x1a,0xff,0xe4,0x07,0x7f,0x07,0x5a,0x00,0x13,0x00,0x25,0x00,0x00,0x01,0x16,0x17,0x06,0x23,0x22,0x26,0x27,0x22,0x00,0x03,0x12,0x00,0x05,0x20,0x00,0x13,0x10,0x00,0x2d,0x01,0x26,0x35,0x34,0x37,0x36,0x37,0x04,0x00,0x13,0x02,0x00,0x21,0x24,0x00,0x11,0x12,0x00,0x03,0x3d,0xc1,0x01,0x0a,0x51,0x31,0x6e,0x6c,0x77,0xfe,0xd9,0x02,0x0a,0x01,0xa7,0x01,0x0f,0x01,0x0c,0x01,0xc0,0x15,0xfe,0x35,0xfe,0xe7,0xfe,0x56,0x27,0x3c,0xaa,0xed,0x01,0x84,0x02,0x42,0x01,0x23,0xfd,0xfa,0xfe,0x62,0xfe,0x70,0xfd,0xf2,0x02,0x01,0x6d,0x06,0x92,0x22,0x7d,0x3f,0x50,0x01,0xfe,0x7b,0xfe,0xf5,0xfe,0x81,0xfe,0xc0,0x05,0x01,0x2c,0x01,0x94,0x01,0xb3,0x01,0x71,0x09,0x08,0x0b,0x43,0x25,0x24,0x15,0x08,0x09,0xfe,0x33,0xfd,0xe8,0xfe,0x2c,0xfe,0x4c,0x01,0x01,0xe8,0x01,0xaa,0x01,0x40,0x01,0xef,0x00,0x00,0x00,0x02,0x00,0x3d,0xff,0xf2,0x06,0x25,0x07,0x65,0x00,0x13,0x00,0x1d,0x00,0x00,0x00,0x29,0x01,0x11,0x06,0x07,0x22,0x35,0x11,0x34,0x37,0x32,0x17,0x36,0x25,0x04,0x00,0x13,0x15,0x06,0x01,0x22,0x07,0x11,0x21,0x24,0x36,0x37,0x26,0x00,0x04,0x7a,0xfe,0x69,0xfe,0x27,0x0d,0x5c,0x64,0x65,0x54,0x11,0x4e,0x01,0x01,0x01,0x95,0x02,0x29,0x11,0x0b,0xfc,0x24,0xe0,0x54,0x01,0xbb,0x01,0x9d,0xf0,0x01,0x01,0xfe,0x5c,0x02,0x22,0xfe,0x2e,0x50,0x0e,0x65,0x06,0xbc,0x4e,0x04,0x4d,0x2b,0x03,0x01,0xfe,0x74,0xfe,0xd0,0x31,0xff,0x03,0x1b,0x2c,0xfc,0xa7,0x06,0xea,0x9d,0xc4,0x01,0x33,0x00,0x02,0x00,0x24,0xfe,0x33,0x07,0xa6,0x07,0x5a,0x00,0x16,0x00,0x2e,0x00,0x00,0x25,0x26,0x27,0x36,0x33,0x16,0x17,0x16,0x33,0x32,0x00,0x13,0x02,0x00,0x25,0x20,0x00,0x03,0x10,0x00,0x05,0x37,0x26,0x04,0x05,0x16,0x17,0x06,0x07,0x26,0x27,0x26,0x27,0x06,0x07,0x24,0x00,0x03,0x12,0x00,0x21,0x04,0x00,0x11,0x02,0x00,0x07,0x03,0xc4,0x33,0x03,0x04,0x68,0x51,0x34,0x61,0x20,0x77,0x01,0x27,0x02,0x0a,0xfe,0x59,0xfe,0xf1,0xfe,0xf4,0xfe,0x40,0x15,0x01,0xcb,0x01,0x19,0x56,0x3e,0x02,0x53,0x01,0x07,0x4d,0x04,0x11,0x4c,0x5b,0x57,0xe9,0x9a,0x88,0xab,0xfe,0x68,0xfd,0xdc,0x01,0x23,0x01,0xfc,0x01,0x9e,0x01,0x90,0x02,0x04,0x02,0xfe,0xa7,0x83,0xeb,0x21,0x44,0x58,0x02,0x37,0x36,0x01,0x86,0x01,0x0a,0x01,0x7f,0x01,0x40,0x05,0xfe,0xd4,0xfe,0x6c,0xfe,0x4d,0xfe,0x8f,0x08,0x08,0x1d,0xdc,0xde,0x3b,0x42,0x4f,0x0d,0x02,0x67,0xd3,0x87,0x16,0x06,0x09,0x01,0xe2,0x02,0x0d,0x01,0xd4,0x01,0xb4,0x01,0xfe,0x18,0xfe,0x56,0xfe,0xb6,0xfe,0x1b,0x14,0x00,0x00,0x02,0x00,0x27,0xff,0xf2,0x06,0x3b,0x07,0x65,0x00,0x19,0x00,0x22,0x00,0x00,0x13,0x32,0x17,0x36,0x25,0x04,0x00,0x13,0x02,0x05,0x01,0x16,0x15,0x14,0x23,0x26,0x27,0x01,0x21,0x11,0x06,0x07,0x22,0x35,0x11,0x34,0x05,0x22,0x07,0x11,0x21,0x20,0x13,0x26,0x00,0x96,0x4c,0x11,0x4e,0x01,0x01,0x01,0x95,0x02,0x29,0x11,0x01,0xfe,0x9c,0x01,0x71,0x1e,0x70,0x57,0x42,0xfe,0x8b,0xfd,0x39,0x0d,0x54,0x6e,0x02,0x03,0xe0,0x54,0x02,0x01,0x02,0x3d,0x01,0x01,0xfe,0x66,0x07,0x65,0x4d,0x2b,0x03,0x01,0xfe,0x74,0xfe,0xd0,0xfe,0x6c,0x90,0xfe,0x3f,0x26,0x2c,0x5c,0x01,0x70,0x01,0xbf,0xfe,0x2a,0x50,0x0e,0x65,0x06,0xbc,0x4e,0xf4,0x25,0xfc,0xa7,0x01,0x8d,0xc4,0x01,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x2a,0xff,0xe3,0x06,0x0b,0x07,0x5c,0x00,0x21,0x00,0x00,0x01,0x04,0x17,0x16,0x17,0x06,0x07,0x22,0x26,0x25,0x04,0x03,0x16,0x00,0x13,0x02,0x05,0x24,0x27,0x26,0x27,0x36,0x37,0x32,0x17,0x16,0x05,0x24,0x37,0x34,0x24,0x03,0x12,0x25,0x03,0x63,0x01,0x70,0xe5,0x52,0x01,0x10,0x46,0x3f,0xcc,0xfe,0xb5,0xfd,0xa8,0x07,0x01,0x04,0xd9,0x01,0x16,0xfd,0x89,0xfe,0x6e,0xd8,0x52,0x01,0x06,0x50,0x2b,0x4e,0xcc,0x01,0x26,0x01,0xa3,0x0b,0xfb,0x2b,0x01,0x1a,0x03,0x1e,0x07,0x5c,0x02,0x91,0x34,0x53,0x57,0x01,0xa0,0x0b,0x1f,0xfe,0x73,0xf4,0xfe,0xf9,0xfe,0x8c,0xfe,0x7d,0x14,0x11,0x85,0x3e,0x44,0x66,0x01,0x3f,0x6a,0x07,0x1d,0xaf,0xe5,0xf4,0x01,0x97,0x02,0x54,0x1a,0x00,0x00,0x01,0x00,0x01,0xff,0xfc,0x05,0x91,0x07,0x44,0x00,0x10,0x00,0x00,0x01,0x21,0x22,0x35,0x34,0x33,0x21,0x32,0x15,0x14,0x23,0x21,0x03,0x14,0x23,0x22,0x27,0x02,0x61,0xfe,0x0c,0x6c,0x71,0x04,0xae,0x71,0x6c,0xfe,0x17,0x02,0x67,0x71,0x01,0x06,0x71,0x76,0x5d,0x5d,0x76,0xf9,0xe8,0x5d,0x5d,0x00,0x00,0x00,0x00,0x01,0x00,0x16,0xff,0xfc,0x06,0x02,0x07,0x5b,0x00,0x1b,0x00,0x00,0x13,0x36,0x33,0x16,0x17,0x02,0x11,0x12,0x00,0x05,0x32,0x37,0x11,0x36,0x33,0x32,0x15,0x11,0x14,0x07,0x22,0x27,0x06,0x07,0x24,0x00,0x03,0x10,0x63,0x0c,0x64,0x68,0x01,0x4a,0x01,0x01,0x9a,0x01,0x70,0xcc,0x5e,0x0d,0x64,0x6a,0x65,0x62,0x11,0x58,0xed,0xfe,0x6b,0xfd,0xd7,0x11,0x06,0xdf,0x74,0x02,0x79,0xfd,0x7d,0xfe,0xd6,0xfe,0xd8,0xfe,0xcd,0x01,0x54,0x05,0xcb,0x6d,0x6f,0xf9,0x62,0x4e,0x04,0x4d,0x49,0x03,0x01,0x01,0x8c,0x01,0x9e,0x01,0x48,0x00,0x00,0x00,0x00,0x01,0x00,0x02,0xff,0xfe,0x06,0x43,0x07,0x48,0x00,0x14,0x00,0x00,0x09,0x01,0x36,0x33,0x16,0x15,0x06,0x07,0x01,0x06,0x07,0x23,0x26,0x27,0x01,0x26,0x27,0x34,0x37,0x32,0x17,0x03,0x23,0x02,0x3b,0x2a,0x5a,0x61,0x08,0x18,0xfd,0x85,0x26,0x5f,0x01,0x5f,0x26,0xfd,0x85,0x18,0x08,0x57,0x64,0x2a,0x01,0x64,0x05,0x60,0x84,0x10,0x69,0x37,0x35,0xfa,0x14,0x76,0x03,0x03,0x76,0x05,0xec,0x35,0x37,0x69,0x10,0x84,0x00,0x01,0x00,0x02,0xff,0xfe,0x09,0x63,0x07,0x48,0x00,0x29,0x00,0x00,0x09,0x01,0x06,0x07,0x23,0x26,0x27,0x01,0x26,0x27,0x34,0x37,0x32,0x17,0x09,0x01,0x36,0x37,0x36,0x37,0x32,0x17,0x36,0x33,0x16,0x17,0x16,0x17,0x09,0x01,0x36,0x33,0x16,0x15,0x06,0x07,0x01,0x06,0x07,0x23,0x26,0x27,0x04,0xb3,0xfe,0xf5,0x26,0x5f,0x01,0x5f,0x26,0xfd,0x85,0x18,0x08,0x57,0x67,0x2a,0x02,0x39,0x01,0x19,0x0a,0x0d,0x10,0x42,0x07,0x06,0x07,0x07,0x42,0x10,0x0d,0x0a,0x01,0x1a,0x02,0x37,0x2a,0x64,0x5b,0x08,0x18,0xfd,0x85,0x26,0x5f,0x01,0x5f,0x26,0x02,0xd0,0xfd,0xa7,0x76,0x03,0x03,0x76,0x05,0xec,0x35,0x37,0x69,0x10,0x84,0xfa,0xa0,0x02,0x68,0x20,0x18,0x40,0x0c,0x01,0x01,0x0c,0x40,0x18,0x20,0xfd,0x98,0x05,0x60,0x84,0x10,0x69,0x37,0x35,0xfa,0x14,0x76,0x03,0x03,0x76,0x00,0x01,0x00,0x12,0xff,0xf4,0x05,0x53,0x07,0x4f,0x00,0x1f,0x00,0x00,0x09,0x01,0x26,0x27,0x34,0x37,0x32,0x17,0x09,0x01,0x36,0x33,0x16,0x15,0x06,0x07,0x09,0x01,0x16,0x17,0x14,0x07,0x22,0x27,0x09,0x01,0x06,0x23,0x26,0x35,0x36,0x37,0x01,0xf9,0xfe,0x40,0x1d,0x0a,0x53,0x63,0x37,0x01,0xaf,0x01,0xb8,0x37,0x63,0x53,0x0a,0x1d,0xfe,0x37,0x01,0xc9,0x1d,0x0a,0x53,0x63,0x37,0xfe,0x48,0xfe,0x51,0x37,0x63,0x53,0x0a,0x1d,0x03,0xa2,0x02,0xc8,0x35,0x37,0x69,0x10,0x84,0xfd,0x5f,0x02,0x97,0x84,0x10,0x69,0x37,0x35,0xfd,0x42,0xfd,0x41,0x35,0x37,0x69,0x10,0x84,0x02,0x97,0xfd,0x5f,0x84,0x10,0x69,0x37,0x35,0x00,0x00,0x00,0x01,0x00,0x21,0xff,0xff,0x05,0xc0,0x07,0x4f,0x00,0x15,0x00,0x00,0x09,0x01,0x26,0x27,0x34,0x37,0x32,0x17,0x09,0x01,0x36,0x33,0x16,0x15,0x06,0x07,0x01,0x11,0x14,0x07,0x26,0x27,0x02,0x7d,0xfd,0xcd,0x1f,0x0a,0x64,0x5f,0x36,0x01,0xd2,0x01,0xdb,0x36,0x5f,0x64,0x0a,0x1f,0xfd,0xc2,0x6d,0x6e,0x01,0x02,0x23,0x04,0x47,0x35,0x37,0x69,0x10,0x84,0xfc,0x76,0x03,0x80,0x84,0x10,0x69,0x37,0x35,0xfb,0xc3,0xfe,0x4d,0x6a,0x07,0x07,0x6a,0x00,0x00,0x00,0x00,0x01,0x00,0x31,0xff,0xfe,0x05,0xb9,0x07,0x3f,0x00,0x17,0x00,0x00,0x08,0x01,0x35,0x21,0x22,0x27,0x36,0x37,0x25,0x16,0x15,0x02,0x00,0x06,0x15,0x05,0x32,0x17,0x06,0x07,0x21,0x26,0x35,0x10,0x01,0x43,0x03,0x83,0xfb,0xf9,0x7f,0x0f,0x06,0x88,0x04,0x7a,0x80,0x0a,0xfc,0x5a,0xdb,0x03,0xdf,0x7f,0x0f,0x06,0x88,0xfb,0xa4,0x80,0x02,0xb8,0x02,0xb5,0xfc,0x67,0x69,0x05,0x01,0x0b,0x87,0xfe,0x7a,0xfd,0x17,0xe7,0x7a,0x01,0x71,0x68,0x05,0x09,0x87,0x01,0x02,0x00,0x00,0x00,0x00,0x01,0x00,0xaa,0xff,0x21,0x02,0xd0,0x08,0x26,0x00,0x11,0x00,0x00,0x13,0x34,0x33,0x25,0x16,0x15,0x06,0x07,0x21,0x11,0x25,0x16,0x17,0x14,0x07,0x25,0x22,0x35,0xaa,0x6c,0x01,0x50,0x6a,0x02,0x5c,0xfe,0xec,0x01,0x14,0x5c,0x02,0x6a,0xfe,0xb0,0x6c,0x07,0xa1,0x83,0x02,0x0b,0x4e,0x67,0x02,0xf8,0x7f,0x01,0x02,0x68,0x4e,0x0b,0x02,0x83,0x00,0x00,0x00,0x01,0x00,0x0f,0xff,0x8e,0x03,0x07,0x07,0xf9,0x00,0x0d,0x00,0x00,0x12,0x37,0x16,0x17,0x01,0x16,0x15,0x06,0x07,0x26,0x27,0x01,0x26,0x35,0x0f,0x6c,0x4f,0x0c,0x02,0x1a,0x17,0x0b,0x46,0x48,0x1a,0xfd,0xe1,0x26,0x07,0xf7,0x02,0x11,0x5e,0xf8,0xcb,0x2a,0x44,0x58,0x01,0x05,0x42,0x07,0x32,0x41,0x54,0x00,0x00,0x01,0x00,0x50,0xff,0x21,0x02,0x76,0x08,0x26,0x00,0x11,0x00,0x00,0x05,0x14,0x23,0x05,0x26,0x35,0x36,0x37,0x05,0x11,0x21,0x26,0x27,0x34,0x37,0x05,0x32,0x15,0x02,0x76,0x6c,0xfe,0xb0,0x6a,0x02,0x5c,0x01,0x14,0xfe,0xec,0x5c,0x02,0x6a,0x01,0x50,0x6c,0x5a,0x83,0x02,0x0b,0x4e,0x68,0x02,0x01,0x07,0x81,0x02,0x67,0x4e,0x0b,0x02,0x83,0x00,0x00,0x00,0x01,0xff,0xa6,0xfe,0xdd,0x04,0xd8,0xff,0x90,0x00,0x09,0x00,0x00,0x01,0x21,0x26,0x27,0x36,0x33,0x21,0x32,0x15,0x06,0x04,0x76,0xfb,0x90,0x5e,0x02,0x02,0x5d,0x04,0x72,0x61,0x02,0xfe,0xdd,0x01,0x5d,0x55,0x5c,0x56,0x00,0x00,0x01,0x00,0x4a,0x05,0x23,0x02,0x6b,0x06,0x13,0x00,0x0e,0x00,0x00,0x00,0x15,0x06,0x07,0x26,0x25,0x26,0x27,0x36,0x33,0x32,0x17,0x1e,0x01,0x17,0x02,0x6b,0x01,0x34,0x87,0xfe,0xd5,0x37,0x03,0x07,0x3e,0x34,0x4b,0xa9,0x62,0x21,0x05,0x82,0x2a,0x2d,0x08,0x07,0x6c,0x16,0x2a,0x3d,0x2a,0x3b,0x0f,0x0b,0x00,0x00,0x02,0x00,0x3e,0xff,0xf9,0x04,0xca,0x04,0x93,0x00,0x09,0x00,0x26,0x00,0x00,0x25,0x36,0x24,0x37,0x34,0x25,0x06,0x04,0x07,0x16,0x01,0x13,0x06,0x07,0x26,0x2f,0x01,0x06,0x21,0x24,0x03,0x36,0x00,0x25,0x32,0x17,0x2e,0x01,0x27,0x22,0x06,0x23,0x26,0x35,0x36,0x24,0x37,0x04,0x12,0x01,0xb0,0xc0,0x01,0x6c,0x07,0xfe,0xf3,0xaa,0xfe,0xd8,0x01,0x06,0x03,0xad,0x14,0x07,0x5f,0x55,0x0a,0x06,0xef,0xfe,0x8b,0xfe,0xa6,0x03,0x01,0x01,0x8c,0x01,0x00,0xd2,0x4e,0x01,0x83,0xb7,0xcd,0x8e,0x4d,0x49,0x06,0x01,0x15,0xdb,0x01,0x27,0xd9,0xb9,0x0c,0x98,0x80,0x7d,0x0a,0x06,0xaa,0x6e,0x8d,0x02,0x0c,0xfd,0xb5,0x70,0x0a,0x09,0x40,0x63,0xb3,0x12,0x01,0x39,0xb6,0x01,0x10,0x14,0x2d,0x5d,0x77,0x0c,0x69,0x08,0x60,0x4e,0x70,0x05,0x07,0xfe,0xf5,0x00,0x00,0x02,0x00,0x4b,0xff,0xef,0x04,0xce,0x07,0x56,0x00,0x09,0x00,0x1c,0x00,0x00,0x01,0x06,0x00,0x07,0x14,0x33,0x36,0x00,0x37,0x26,0x01,0x36,0x37,0x16,0x17,0x11,0x12,0x21,0x04,0x13,0x02,0x00,0x05,0x22,0x27,0x06,0x23,0x22,0x27,0x03,0x5c,0xc0,0xfe,0x94,0x07,0xd8,0xad,0x01,0x3f,0x17,0x06,0xfc,0x4d,0x03,0x67,0x61,0x01,0xe5,0x01,0x6b,0x01,0x5a,0x0d,0x01,0xfe,0x74,0xfe,0xc4,0x96,0x58,0x1e,0x56,0x57,0x01,0x03,0x9e,0x02,0xfe,0x82,0x9e,0xcd,0x01,0x01,0x31,0xf0,0xc9,0x03,0x44,0x73,0x01,0x02,0x80,0xfc,0x37,0x01,0x5d,0x12,0xfe,0x81,0xfe,0xf8,0xfe,0x34,0x14,0x26,0x26,0x71,0x00,0x00,0x00,0x00,0x01,0x00,0x39,0xff,0xec,0x04,0x10,0x04,0x88,0x00,0x19,0x00,0x00,0x01,0x04,0x17,0x06,0x07,0x2e,0x01,0x23,0x0e,0x01,0x07,0x12,0x17,0x3e,0x02,0x37,0x16,0x17,0x06,0x04,0x07,0x24,0x03,0x12,0x00,0x02,0x6c,0x01,0x64,0x05,0x02,0x58,0x35,0x7d,0x58,0x83,0xee,0x02,0x14,0xf4,0x8d,0xb8,0x2b,0x47,0x4d,0x06,0x09,0xfe,0xeb,0xdd,0xfe,0x2f,0x0b,0x01,0x01,0x1e,0x04,0x88,0x0b,0x99,0x53,0x05,0x01,0x37,0x01,0xff,0xbf,0xfe,0xb5,0x06,0x01,0xa5,0x63,0x01,0x04,0x64,0x74,0xf1,0x05,0x05,0x01,0xfc,0x01,0x1f,0x01,0x67,0x00,0x02,0x00,0x34,0xff,0xf9,0x04,0xe8,0x07,0x47,0x00,0x0a,0x00,0x20,0x00,0x00,0x25,0x36,0x00,0x37,0x27,0x34,0x23,0x06,0x00,0x07,0x16,0x01,0x03,0x36,0x37,0x16,0x17,0x1a,0x01,0x17,0x06,0x07,0x26,0x35,0x27,0x02,0x21,0x24,0x03,0x12,0x00,0x25,0x32,0x01,0xa6,0xc0,0x01,0x6c,0x0a,0x03,0xd8,0xad,0xfe,0xc1,0x1c,0x06,0x02,0xe5,0x06,0x03,0x6f,0x5a,0x05,0x05,0x33,0x01,0x07,0x5f,0x69,0x1a,0xf9,0xfe,0x8b,0xfe,0xa6,0x03,0x01,0x01,0x8c,0x01,0x3c,0x90,0xb9,0x0c,0x01,0x7e,0x98,0x56,0x7d,0x01,0xfe,0xcf,0xf0,0xd3,0x03,0x96,0x02,0x80,0x76,0x02,0x0e,0x6b,0xfc,0x91,0xfd,0x76,0x5b,0x70,0x0a,0x09,0x72,0xf9,0xfe,0x85,0x12,0x01,0x7f,0x01,0x08,0x01,0xcc,0x14,0x00,0x02,0x00,0x39,0xff,0xec,0x04,0x82,0x04,0x93,0x00,0x07,0x00,0x1d,0x00,0x00,0x01,0x34,0x23,0x04,0x07,0x16,0x17,0x20,0x16,0x05,0x26,0x27,0x12,0x05,0x36,0x37,0x36,0x33,0x16,0x17,0x06,0x04,0x05,0x24,0x03,0x12,0x00,0x25,0x04,0x13,0x03,0xb3,0xd7,0xfe,0xba,0x57,0x93,0x66,0x01,0x78,0xcb,0xfd,0xc7,0xbf,0x6c,0x09,0x01,0x64,0xa0,0x88,0x41,0x41,0x53,0x01,0x02,0xfe,0xdd,0xfe,0xdc,0xfe,0x27,0x27,0x01,0x01,0x7e,0x01,0x23,0x01,0x9d,0x04,0x03,0x4c,0x88,0x1c,0xd4,0x08,0x02,0xbc,0x0c,0x0a,0x01,0xfe,0xaa,0x13,0x02,0x78,0x3d,0x01,0x60,0x4e,0xce,0x02,0x38,0x01,0xe0,0x01,0x27,0x01,0x5b,0x0d,0x0f,0xfe,0xcc,0x00,0x00,0x01,0xff,0xc6,0x00,0x00,0x02,0x9d,0x07,0x49,0x00,0x1e,0x00,0x00,0x01,0x1e,0x01,0x17,0x06,0x07,0x2e,0x01,0x27,0x06,0x07,0x33,0x16,0x17,0x06,0x07,0x23,0x13,0x14,0x07,0x22,0x27,0x03,0x23,0x22,0x35,0x34,0x3f,0x01,0x3e,0x01,0x01,0x8c,0x87,0x89,0x01,0x08,0x46,0x1e,0x60,0x4a,0x64,0x04,0xeb,0x4d,0x04,0x08,0x4d,0xea,0x0b,0x64,0x60,0x0e,0x0d,0x2d,0x55,0x5a,0x31,0x05,0x94,0x07,0x49,0x01,0x48,0x47,0x4a,0x02,0x01,0x1b,0x02,0x0c,0xce,0x0b,0x42,0x5a,0x08,0xfb,0x79,0x70,0x0b,0x7c,0x04,0x85,0x5b,0x4f,0x05,0x04,0xac,0xe8,0x00,0x00,0x02,0x00,0x27,0xfd,0xe4,0x04,0xbf,0x04,0x68,0x00,0x0a,0x00,0x28,0x00,0x00,0x25,0x36,0x00,0x37,0x27,0x34,0x23,0x06,0x00,0x07,0x16,0x08,0x01,0x07,0x2e,0x01,0x35,0x36,0x37,0x32,0x16,0x33,0x3e,0x01,0x37,0x13,0x02,0x21,0x24,0x03,0x12,0x00,0x25,0x32,0x17,0x36,0x33,0x16,0x17,0x13,0x03,0x01,0x99,0xc0,0x01,0x6c,0x0a,0x03,0xd8,0xad,0xfe,0xc1,0x1c,0x06,0x03,0xc4,0xfe,0xd7,0xe7,0xc0,0xa9,0x03,0x56,0x4f,0x6d,0x59,0x67,0xde,0x02,0x03,0xfc,0xfe,0x8b,0xfe,0xa6,0x03,0x01,0x01,0x8c,0x01,0x3c,0x96,0x58,0x1e,0x55,0x61,0x01,0x0c,0x09,0xaf,0x0c,0x01,0x7e,0x98,0x56,0x7d,0x01,0xfe,0xcf,0xf0,0xd3,0xfe,0x82,0xfe,0xb8,0x05,0x01,0x4d,0x50,0x45,0x14,0x30,0x01,0xc3,0xe9,0x01,0x12,0xfe,0x85,0x12,0x01,0x7f,0x01,0x08,0x01,0xcc,0x14,0x26,0x26,0x01,0x70,0xfd,0xeb,0xfe,0x58,0x00,0x00,0x01,0x00,0x42,0x00,0x03,0x04,0x66,0x07,0x3d,0x00,0x1b,0x00,0x00,0x37,0x26,0x35,0x02,0x35,0x36,0x37,0x16,0x17,0x13,0x12,0x25,0x04,0x13,0x14,0x03,0x06,0x23,0x26,0x35,0x12,0x35,0x26,0x27,0x22,0x00,0x03,0x06,0xc5,0x67,0x1c,0x0d,0x58,0x60,0x07,0x09,0x9e,0x01,0x4f,0x01,0x5d,0x05,0x14,0x0a,0x68,0x55,0x10,0x0a,0x93,0x92,0xfe,0xf4,0x32,0x05,0x07,0x0c,0x68,0x06,0x17,0x4c,0x5e,0x01,0x09,0x7a,0xfc,0x5a,0x01,0x6d,0x07,0x0a,0xfe,0x44,0xf2,0xfe,0x98,0x65,0x08,0x63,0x01,0x66,0xdf,0xfd,0x11,0xfe,0x83,0xfe,0x2a,0x5e,0x00,0x00,0x00,0x02,0x00,0x52,0xff,0xf9,0x02,0x3e,0x06,0x99,0x00,0x07,0x00,0x18,0x00,0x00,0x01,0x16,0x15,0x06,0x07,0x26,0x27,0x36,0x12,0x17,0x03,0x16,0x33,0x32,0x36,0x33,0x32,0x17,0x06,0x07,0x24,0x03,0x13,0x36,0x33,0x01,0x05,0x69,0x13,0x65,0x72,0x02,0x16,0x8d,0x01,0x09,0x14,0x5d,0x1c,0x33,0x22,0x35,0x0a,0x02,0xbc,0xfe,0xd7,0x05,0x0b,0x05,0x62,0x06,0x99,0x1a,0x6c,0x68,0x0c,0x05,0x8f,0x66,0xfd,0xe5,0x6d,0xfd,0x8f,0xda,0x12,0x4f,0x8f,0x01,0x17,0x01,0x9a,0x02,0x69,0x6b,0x00,0x02,0xfe,0xb5,0xfe,0x5c,0x01,0x9c,0x07,0x12,0x00,0x08,0x00,0x1b,0x00,0x00,0x01,0x16,0x17,0x07,0x06,0x23,0x22,0x27,0x34,0x13,0x16,0x17,0x13,0x0a,0x01,0x07,0x24,0x27,0x36,0x37,0x32,0x16,0x33,0x32,0x36,0x13,0x03,0x36,0x01,0x06,0x80,0x0a,0x0a,0x27,0x58,0x5b,0x13,0x8a,0x4f,0x13,0x17,0x01,0xe3,0xf2,0xff,0x00,0x11,0x03,0x3d,0x2e,0x56,0x51,0x82,0x84,0x01,0x15,0x05,0x07,0x12,0x01,0x6c,0x3d,0x5d,0x70,0x7d,0xfd,0x9d,0x03,0x69,0xfc,0xed,0xfe,0x78,0xfe,0xd4,0x06,0x10,0x85,0x54,0x0c,0x26,0xca,0x01,0x41,0x02,0xfa,0x57,0x00,0x00,0x01,0x00,0x3e,0xff,0xf9,0x04,0x2e,0x07,0x2b,0x00,0x1b,0x00,0x00,0x12,0x37,0x32,0x15,0x03,0x01,0x36,0x37,0x32,0x17,0x06,0x07,0x05,0x01,0x16,0x17,0x06,0x07,0x26,0x27,0x01,0x07,0x13,0x06,0x23,0x26,0x27,0x13,0x4b,0x6f,0x66,0x09,0x01,0xda,0x50,0x3b,0x68,0x07,0x08,0x7c,0xfe,0xcf,0x01,0xd9,0x1e,0x01,0x03,0x52,0x57,0x15,0xfe,0x0e,0x5b,0x02,0x01,0x6b,0x75,0x03,0x0b,0x07,0x23,0x08,0x6f,0xfc,0x3f,0x01,0x31,0x43,0x01,0x73,0x45,0x3d,0xc5,0xfd,0xfb,0x24,0x3f,0x4a,0x0b,0x0b,0x2a,0x02,0x21,0x3d,0xfe,0x6f,0x81,0x01,0x78,0x06,0x32,0x00,0x00,0x00,0x00,0x01,0x00,0x38,0xff,0xf9,0x02,0x24,0x07,0x4a,0x00,0x10,0x00,0x00,0x00,0x17,0x03,0x16,0x33,0x32,0x36,0x33,0x32,0x17,0x06,0x07,0x24,0x03,0x13,0x36,0x33,0x01,0x10,0x01,0x0e,0x14,0x5d,0x1c,0x33,0x22,0x35,0x0a,0x02,0xbc,0xfe,0xd7,0x05,0x10,0x05,0x62,0x07,0x4a,0x6d,0xfa,0xc3,0xda,0x12,0x4f,0x8f,0x01,0x17,0x01,0x9a,0x05,0x35,0x6b,0x00,0x00,0x00,0x01,0x00,0x46,0xff,0xfa,0x07,0x41,0x04,0x88,0x00,0x2e,0x00,0x00,0x01,0x06,0x03,0x06,0x23,0x26,0x35,0x12,0x35,0x26,0x27,0x22,0x00,0x03,0x06,0x07,0x26,0x35,0x0a,0x01,0x35,0x36,0x37,0x16,0x17,0x13,0x12,0x25,0x16,0x17,0x36,0x37,0x04,0x13,0x14,0x03,0x06,0x23,0x26,0x35,0x12,0x35,0x26,0x27,0x22,0x07,0x06,0x04,0x85,0x03,0x11,0x0a,0x68,0x55,0x10,0x0a,0x93,0x92,0xfe,0xf4,0x32,0x05,0x66,0x67,0x07,0x2e,0x0d,0x58,0x6a,0x07,0x10,0xa8,0x01,0x4f,0xe5,0x51,0x99,0xed,0x01,0x5d,0x05,0x14,0x0a,0x68,0x55,0x10,0x0a,0x93,0x92,0x86,0x21,0x02,0x92,0xe6,0xfe,0xb9,0x65,0x08,0x63,0x01,0x66,0xdf,0xfd,0x11,0xfe,0x83,0xfe,0x20,0x5e,0x09,0x0c,0x68,0x01,0xcd,0x01,0xa2,0x4c,0x5e,0x01,0x09,0x7a,0xfe,0xf8,0x01,0x81,0x07,0x07,0xc0,0xc2,0x05,0x0a,0xfe,0x44,0xf2,0xfe,0x98,0x65,0x08,0x63,0x01,0x66,0xdf,0xfd,0x11,0xbe,0x2f,0x00,0x01,0x00,0x46,0xff,0xfa,0x04,0x7b,0x04,0x82,0x00,0x1c,0x00,0x00,0x17,0x26,0x35,0x0a,0x01,0x35,0x36,0x37,0x16,0x1f,0x01,0x12,0x25,0x04,0x13,0x14,0x03,0x06,0x23,0x26,0x35,0x12,0x35,0x26,0x27,0x22,0x00,0x03,0x06,0xd8,0x67,0x07,0x24,0x0d,0x58,0x6a,0x07,0x06,0xa8,0x01,0x4f,0x01,0x5d,0x05,0x14,0x0a,0x68,0x55,0x10,0x0a,0x93,0x92,0xfe,0xf4,0x32,0x05,0x02,0x0c,0x68,0x01,0xc3,0x01,0xa2,0x4c,0x5e,0x01,0x09,0x7a,0xf4,0x01,0x6d,0x07,0x0a,0xfe,0x44,0xf2,0xfe,0x98,0x65,0x08,0x63,0x01,0x66,0xdf,0xfd,0x11,0xfe,0x83,0xfe,0x2a,0x5e,0x00,0x00,0x00,0x00,0x02,0x00,0x2d,0xff,0xe9,0x05,0x16,0x04,0x94,0x00,0x0d,0x00,0x19,0x00,0x00,0x01,0x17,0x16,0x00,0x13,0x10,0x00,0x05,0x27,0x24,0x00,0x03,0x36,0x00,0x03,0x12,0x05,0x17,0x24,0x13,0x37,0x34,0x24,0x2f,0x01,0x04,0x02,0x6a,0x4a,0xca,0x01,0x6d,0x2b,0xfe,0xc7,0xfe,0xd7,0x35,0xfe,0xfb,0xfe,0xbc,0x09,0x0e,0x01,0x19,0x5c,0x17,0x01,0x5b,0x51,0x01,0x3b,0x4f,0x0a,0xff,0x00,0xbb,0x33,0xfe,0xc4,0x04,0x94,0x02,0x0d,0xfe,0xe0,0xfe,0xe0,0xfe,0xea,0xfe,0xcd,0x13,0x07,0x1a,0x01,0x41,0x01,0x27,0xe5,0x01,0x2e,0xfd,0xde,0xfe,0xb2,0x61,0x0a,0x1e,0x01,0x0b,0x2f,0xc7,0xee,0x0f,0x01,0x29,0x00,0x00,0x00,0x02,0x00,0x45,0xfd,0xe7,0x04,0xdb,0x04,0x7c,0x00,0x0a,0x00,0x1e,0x00,0x00,0x01,0x06,0x00,0x07,0x17,0x14,0x17,0x36,0x00,0x37,0x26,0x01,0x13,0x06,0x07,0x22,0x27,0x03,0x36,0x37,0x16,0x15,0x17,0x12,0x21,0x04,0x13,0x02,0x00,0x05,0x22,0x03,0x69,0xc0,0xfe,0x94,0x0a,0x03,0xd8,0xad,0x01,0x3f,0x1c,0x06,0xfd,0x2b,0x08,0x0a,0x54,0x67,0x0a,0x2f,0x07,0x5f,0x69,0x06,0xef,0x01,0x75,0x01,0x5a,0x03,0x01,0xfe,0x74,0xfe,0xc4,0x83,0x03,0xbc,0x0c,0xfe,0x8c,0x98,0x56,0x7d,0x0a,0x01,0x01,0x31,0xf0,0xd3,0xfc,0x64,0xfe,0x3b,0x70,0x04,0x77,0x05,0x9d,0x70,0x0a,0x09,0x72,0xef,0x01,0x71,0x12,0xfe,0x81,0xfe,0xf8,0xfe,0x34,0x14,0x00,0x00,0x00,0x02,0x00,0x27,0xfd,0xdd,0x06,0x0a,0x04,0x68,0x00,0x0a,0x00,0x24,0x00,0x00,0x25,0x36,0x00,0x37,0x27,0x34,0x23,0x06,0x00,0x07,0x16,0x00,0x17,0x32,0x36,0x33,0x16,0x17,0x06,0x07,0x24,0x0b,0x01,0x02,0x21,0x24,0x03,0x12,0x00,0x25,0x32,0x17,0x36,0x33,0x32,0x17,0x13,0x01,0x99,0xc0,0x01,0x6c,0x0a,0x03,0xd8,0xad,0xfe,0xc1,0x1c,0x06,0x03,0xd0,0x93,0x22,0x2e,0x19,0x45,0x07,0x01,0xcf,0xfe,0xc4,0x10,0x0b,0xea,0xfe,0x8b,0xfe,0xa6,0x03,0x01,0x01,0x8c,0x01,0x3c,0x96,0x58,0x1e,0x41,0x45,0x13,0x1d,0xaf,0x0c,0x01,0x7e,0x98,0x56,0x7d,0x01,0xfe,0xcf,0xf0,0xd3,0xfd,0xfe,0x01,0x0d,0x0a,0x5a,0x75,0x03,0x28,0x01,0x8a,0x01,0xb3,0xfe,0xad,0x12,0x01,0x7f,0x01,0x08,0x01,0xcc,0x14,0x26,0x26,0x53,0xfb,0x8f,0x00,0x00,0x00,0x01,0x00,0x33,0x00,0x00,0x02,0xfd,0x04,0x89,0x00,0x16,0x00,0x00,0x13,0x16,0x17,0x36,0x37,0x04,0x17,0x06,0x07,0x2e,0x01,0x27,0x06,0x07,0x13,0x06,0x23,0x26,0x27,0x02,0x26,0x35,0x36,0x92,0x63,0x0b,0x41,0x94,0x01,0x12,0x16,0x02,0x47,0x53,0x42,0x43,0xab,0x12,0x1a,0x0e,0x63,0x5a,0x07,0x0c,0x28,0x0e,0x04,0x89,0x06,0x5d,0x53,0x0b,0x12,0xc9,0x59,0x0a,0x01,0x74,0x0a,0x17,0xa0,0xfd,0x6b,0x79,0x01,0x72,0x02,0x99,0xc1,0x5d,0x59,0x00,0x00,0x00,0x00,0x01,0x00,0x45,0xff,0xe9,0x04,0x04,0x04,0x99,0x00,0x20,0x00,0x00,0x01,0x17,0x04,0x17,0x06,0x07,0x2e,0x01,0x23,0x22,0x06,0x07,0x14,0x04,0x13,0x07,0x02,0x05,0x23,0x24,0x27,0x34,0x37,0x32,0x16,0x17,0x24,0x37,0x34,0x24,0x27,0x37,0x12,0x02,0x32,0x45,0x01,0x32,0x0e,0x04,0x46,0x40,0x6d,0x64,0x91,0x9d,0x08,0x02,0xb0,0x2e,0x05,0x38,0xfe,0x5b,0x3a,0xfe,0x70,0x13,0x3c,0x3c,0xa3,0xb8,0x01,0x0b,0x0a,0xfd,0x3e,0x1b,0x02,0x3f,0x04,0x99,0x02,0x15,0xac,0x45,0x0d,0x03,0x4a,0x45,0x54,0x76,0x04,0xfe,0xbe,0x58,0xfe,0xea,0x25,0x1e,0xf5,0x47,0x10,0x8e,0x04,0x07,0x9e,0xad,0x05,0xfc,0x3b,0x01,0x29,0x00,0x00,0x00,0x00,0x01,0x00,0x12,0xff,0xff,0x03,0x78,0x06,0x3e,0x00,0x21,0x00,0x00,0x01,0x16,0x17,0x06,0x2b,0x01,0x27,0x03,0x12,0x17,0x36,0x37,0x36,0x33,0x32,0x15,0x02,0x05,0x24,0x0b,0x01,0x23,0x22,0x27,0x36,0x37,0x33,0x35,0x37,0x36,0x33,0x16,0x17,0x07,0x02,0xd9,0x5a,0x05,0x08,0x5c,0x92,0xbb,0x04,0x02,0xb4,0x69,0x12,0x1d,0x52,0x55,0x2c,0xfe,0xed,0xfe,0x81,0x03,0x01,0x40,0x5c,0x08,0x05,0x5a,0x5d,0x04,0x0c,0x62,0x55,0x0a,0x01,0x05,0x00,0x07,0x5a,0x5b,0x01,0xfd,0x93,0xfe,0xfc,0x09,0x05,0x72,0x5a,0x71,0xfe,0xe3,0x0f,0x0c,0x01,0xd0,0x02,0x69,0x5b,0x5a,0x07,0x01,0xe4,0x59,0x07,0x62,0xd5,0x00,0x00,0x01,0x00,0x35,0x00,0x00,0x04,0x74,0x04,0x8b,0x00,0x1c,0x00,0x00,0x01,0x16,0x15,0x1a,0x01,0x15,0x06,0x07,0x26,0x27,0x03,0x02,0x05,0x24,0x03,0x34,0x13,0x36,0x33,0x16,0x15,0x02,0x15,0x16,0x17,0x32,0x00,0x13,0x36,0x03,0xd8,0x67,0x07,0x2e,0x0d,0x58,0x6a,0x07,0x10,0xa7,0xfe,0xb1,0xfe,0xa3,0x06,0x14,0x0a,0x68,0x55,0x10,0x0a,0x93,0x92,0x01,0x0c,0x32,0x05,0x04,0x87,0x0c,0x68,0xfe,0x3d,0xfe,0x5e,0x4c,0x5e,0x01,0x09,0x7b,0x01,0x07,0xfe,0x79,0x07,0x0a,0x01,0xc2,0xf2,0x01,0x69,0x64,0x08,0x63,0xfe,0x9a,0xdf,0xfd,0x11,0x01,0x7d,0x01,0xd6,0x5e,0x00,0x01,0x00,0x11,0x00,0x04,0x04,0x06,0x04,0x8b,0x00,0x16,0x00,0x00,0x25,0x26,0x27,0x0a,0x01,0x35,0x36,0x37,0x32,0x16,0x13,0x12,0x17,0x36,0x12,0x36,0x33,0x16,0x17,0x14,0x02,0x03,0x06,0x02,0x0f,0x64,0x3f,0xba,0xa1,0x0b,0x54,0x44,0x42,0x70,0x6d,0x3a,0x34,0xe0,0x42,0x4e,0x4a,0x0b,0xa1,0xb9,0x40,0x04,0x01,0xa4,0x01,0xe9,0x01,0x65,0x3a,0x50,0x0a,0x6e,0xfe,0xe4,0xfe,0xea,0x97,0x90,0x02,0x39,0x6e,0x0a,0x50,0x3a,0xfe,0x9b,0xfe,0x17,0xa4,0x00,0x00,0x01,0x00,0x08,0x00,0x04,0x06,0x43,0x04,0x8b,0x00,0x27,0x00,0x00,0x00,0x37,0x16,0x17,0x16,0x12,0x17,0x36,0x12,0x36,0x33,0x16,0x17,0x14,0x02,0x03,0x06,0x07,0x26,0x27,0x02,0x27,0x06,0x03,0x06,0x07,0x26,0x27,0x0a,0x01,0x35,0x36,0x37,0x32,0x16,0x12,0x17,0x36,0x12,0x37,0x02,0xea,0x41,0x36,0x1e,0x21,0xab,0x3a,0x35,0xae,0x42,0x44,0x4a,0x0b,0x89,0x91,0x44,0x5e,0x64,0x3f,0x74,0x4a,0x4b,0x73,0x40,0x5d,0x65,0x43,0x92,0x89,0x0b,0x4a,0x44,0x42,0xab,0x3b,0x34,0xae,0x21,0x04,0x84,0x07,0x07,0x30,0x37,0xfd,0xce,0x97,0x90,0x02,0x39,0x6e,0x0a,0x50,0x3a,0xfe,0x9b,0xfe,0x17,0xa4,0x01,0x01,0xa4,0x01,0xa9,0xbf,0xbf,0xfe,0x57,0xa4,0x01,0x01,0xa4,0x01,0xe9,0x01,0x65,0x3a,0x50,0x0a,0x6e,0xfd,0xce,0x97,0x90,0x02,0x39,0x37,0x00,0x00,0x00,0x01,0x00,0x1c,0x00,0x00,0x04,0x00,0x04,0x80,0x00,0x1f,0x00,0x00,0x09,0x01,0x26,0x27,0x36,0x37,0x16,0x17,0x09,0x01,0x36,0x37,0x16,0x17,0x14,0x07,0x09,0x01,0x16,0x15,0x06,0x07,0x26,0x27,0x09,0x01,0x06,0x07,0x26,0x27,0x36,0x37,0x01,0x8d,0xfe,0xdb,0x4b,0x01,0x06,0x58,0x49,0x32,0x01,0x11,0x01,0x12,0x31,0x4a,0x57,0x06,0x4c,0xfe,0xe3,0x01,0x2d,0x4c,0x06,0x58,0x49,0x31,0xfe,0xe1,0xfe,0xec,0x32,0x49,0x58,0x06,0x01,0x4b,0x02,0x45,0x01,0x4d,0x3b,0x44,0x65,0x0a,0x02,0x56,0xfe,0xd7,0x01,0x29,0x56,0x02,0x0a,0x65,0x44,0x3b,0xfe,0xbc,0xfe,0xa1,0x3a,0x45,0x65,0x0a,0x02,0x57,0x01,0x48,0xfe,0xb7,0x57,0x02,0x0a,0x65,0x45,0x3a,0x00,0x01,0x00,0x32,0xfd,0xe3,0x04,0x55,0x04,0x8b,0x00,0x25,0x00,0x00,0x00,0x05,0x22,0x27,0x26,0x35,0x36,0x37,0x32,0x16,0x33,0x32,0x12,0x11,0x02,0x05,0x24,0x03,0x34,0x13,0x36,0x33,0x16,0x15,0x02,0x15,0x16,0x17,0x32,0x00,0x13,0x36,0x37,0x16,0x15,0x12,0x13,0x10,0x03,0x41,0xfe,0xe3,0x98,0x52,0x3d,0x05,0x3e,0x41,0x51,0x50,0xab,0xbe,0xa8,0xfe,0xb1,0xfe,0xa3,0x05,0x1e,0x0a,0x68,0x55,0x1a,0x0a,0x93,0x92,0x01,0x0c,0x39,0x05,0x66,0x67,0x11,0x01,0xfd,0xe5,0x02,0x29,0x1b,0x4b,0x41,0x1b,0x21,0x01,0x2c,0x01,0xb5,0xfe,0x7f,0x07,0x0a,0x01,0xbc,0xf2,0x01,0x69,0x64,0x08,0x63,0xfe,0x9a,0xdf,0xfd,0x11,0x01,0x7d,0x01,0xd6,0x5e,0x09,0x0c,0x68,0xfe,0x79,0xfe,0xcb,0xfe,0x38,0x00,0x01,0x00,0x32,0x00,0x04,0x03,0x96,0x04,0x7c,0x00,0x15,0x00,0x00,0x01,0x05,0x26,0x27,0x36,0x37,0x21,0x16,0x15,0x14,0x07,0x01,0x21,0x16,0x17,0x06,0x07,0x21,0x26,0x35,0x34,0x37,0x02,0x93,0xfd,0xf5,0x53,0x03,0x0a,0x5f,0x02,0x92,0x69,0x1d,0xfd,0xbc,0x02,0x0b,0x53,0x03,0x0a,0x5f,0xfd,0x6e,0x69,0x1e,0x03,0xb9,0x01,0x11,0x52,0x5b,0x06,0x0f,0x55,0x3a,0x3c,0xfd,0x2a,0x11,0x57,0x57,0x09,0x12,0x55,0x3a,0x3c,0x00,0x00,0x00,0x00,0x01,0x00,0x87,0x02,0xb0,0x03,0x72,0x04,0x0b,0x00,0x17,0x00,0x00,0x00,0x15,0x06,0x07,0x26,0x27,0x26,0x23,0x22,0x07,0x06,0x07,0x26,0x27,0x36,0x37,0x16,0x17,0x16,0x3b,0x01,0x32,0x36,0x37,0x03,0x72,0x2d,0xa6,0x75,0x45,0x48,0x34,0x2b,0x3b,0x15,0x3a,0x2c,0x01,0x2b,0xc3,0x5b,0x49,0x46,0x35,0x04,0x27,0x44,0x3b,0x04,0x02,0x3a,0xca,0x11,0x07,0x19,0x1a,0x4a,0x2c,0x01,0x11,0x3e,0xaa,0x05,0x06,0x19,0x19,0x8e,0x07,0x00,0x00,0xff,0xff,0x00,0x9c,0xfd,0xbd,0x01,0xa0,0x04,0x80,0x00,0x0b,0x00,0x04,0x02,0x6e,0x04,0x7e,0xc0,0x00,0x00,0x02,0x00,0x33,0xff,0xe6,0x04,0x0a,0x07,0x4b,0x00,0x2c,0x00,0x33,0x00,0x00,0x13,0x26,0x03,0x12,0x00,0x25,0x16,0x17,0x13,0x36,0x33,0x16,0x17,0x06,0x07,0x03,0x16,0x17,0x06,0x07,0x26,0x27,0x26,0x27,0x01,0x16,0x17,0x3e,0x02,0x37,0x16,0x17,0x06,0x04,0x07,0x26,0x27,0x07,0x06,0x23,0x26,0x27,0x34,0x37,0x01,0x06,0x07,0x06,0x07,0x16,0x17,0xe2,0xa8,0x07,0x01,0x01,0x1e,0x01,0x14,0x13,0x11,0x9b,0x13,0x3c,0x42,0x01,0x06,0x12,0x78,0xa5,0x03,0x02,0x58,0x35,0x3e,0x12,0x14,0xfe,0xd1,0x26,0x2d,0x8d,0xb8,0x2b,0x47,0x4d,0x06,0x09,0xfe,0xeb,0xdd,0x60,0x4d,0x43,0x1f,0x3a,0x2f,0x06,0x25,0x01,0x87,0x6a,0x62,0x77,0x02,0x09,0x36,0x01,0x20,0x7c,0x01,0x2f,0x01,0x1f,0x01,0x67,0x15,0x01,0x01,0x01,0x8f,0x58,0x05,0x61,0x3c,0x2c,0xfe,0xd3,0x26,0x68,0x53,0x05,0x01,0x1c,0x07,0x06,0xfd,0x0b,0x0c,0x01,0x01,0xa5,0x63,0x01,0x04,0x64,0x74,0xf1,0x05,0x01,0x17,0xa7,0x55,0x04,0x44,0x2c,0x56,0x03,0xee,0x14,0x68,0x80,0xbf,0x94,0x53,0x00,0x00,0x00,0x00,0x01,0x00,0x07,0xff,0xf4,0x05,0xa9,0x07,0x4f,0x00,0x34,0x00,0x00,0x01,0x03,0x05,0x3e,0x01,0x33,0x16,0x17,0x06,0x04,0x07,0x25,0x26,0x27,0x13,0x26,0x27,0x36,0x3f,0x01,0x26,0x27,0x36,0x37,0x12,0x37,0x36,0x25,0x20,0x17,0x16,0x15,0x06,0x23,0x2e,0x01,0x27,0x06,0x07,0x06,0x03,0x21,0x16,0x17,0x06,0x07,0x05,0x07,0x25,0x16,0x17,0x06,0x07,0x01,0x2c,0x28,0x02,0xb3,0xcc,0x89,0x48,0x54,0x01,0x01,0xfe,0xef,0xec,0xfc,0xde,0x53,0x0d,0x2c,0x4c,0x02,0x07,0x56,0x08,0x62,0x03,0x08,0x6d,0x26,0xa8,0xb1,0x01,0x3c,0x01,0x65,0xa1,0x23,0x07,0x57,0x44,0xc9,0xb4,0xc7,0x84,0x77,0x28,0x01,0x50,0x84,0x0c,0x06,0x82,0xfe,0x95,0x07,0x01,0x6a,0x84,0x0c,0x06,0x82,0x02,0xba,0xfe,0x12,0x0c,0x01,0xe9,0x05,0x6a,0x70,0xd6,0x01,0x0b,0x07,0x84,0x02,0x39,0x16,0x49,0x46,0x0e,0x65,0x12,0x53,0x4c,0x09,0x01,0x48,0xb1,0xba,0x07,0x86,0x27,0x3b,0x59,0x07,0x64,0x02,0x01,0x7a,0x61,0xfe,0xf8,0x01,0x58,0x5c,0x0a,0x01,0x5e,0x02,0x02,0x58,0x5b,0x0b,0x00,0x00,0x00,0x02,0x01,0x00,0x05,0x12,0x02,0xde,0x05,0xdc,0x00,0x07,0x00,0x0f,0x00,0x00,0x00,0x15,0x06,0x23,0x22,0x35,0x36,0x37,0x04,0x15,0x06,0x23,0x22,0x35,0x36,0x37,0x01,0xd3,0x14,0x53,0x6c,0x0b,0x52,0x01,0x81,0x13,0x54,0x6c,0x0b,0x52,0x05,0xda,0x6c,0x5c,0x77,0x3f,0x14,0x02,0x6c,0x5c,0x77,0x3f,0x14,0x00,0xff,0xff,0x00,0x16,0x03,0x1e,0x03,0x16,0x07,0x47,0x00,0x63,0x00,0x44,0xff,0xed,0x04,0x88,0x2a,0x3d,0x26,0x66,0x00,0x43,0x00,0x42,0x00,0x5d,0x04,0x41,0x20,0x00,0x40,0x00,0x00,0x00,0x00,0x01,0x00,0x57,0x01,0x13,0x03,0x9f,0x02,0xff,0x00,0x06,0x00,0x00,0x13,0x21,0x11,0x07,0x23,0x11,0x21,0x57,0x03,0x48,0x01,0x62,0xfd,0x1b,0x02,0xff,0xfe,0x15,0x01,0x01,0x88,0x00,0x00,0x01,0x00,0x34,0x05,0x59,0x02,0x9d,0x06,0x0e,0x00,0x0e,0x00,0x00,0x00,0x17,0x06,0x07,0x06,0x0f,0x01,0x26,0x27,0x36,0x33,0x16,0x17,0x36,0x37,0x02,0x93,0x0a,0x05,0x44,0x6d,0x6e,0xd9,0x69,0x03,0x06,0x5d,0x67,0x67,0x65,0x7a,0x06,0x0e,0x4c,0x4d,0x0c,0x0d,0x02,0x01,0x06,0x57,0x4f,0x07,0x01,0x03,0x0e,0x00,0x02,0x00,0x3c,0x03,0x76,0x02,0x68,0x05,0xa2,0x00,0x0b,0x00,0x17,0x00,0x00,0x01,0x22,0x06,0x15,0x14,0x16,0x33,0x32,0x36,0x35,0x34,0x26,0x27,0x32,0x16,0x15,0x14,0x06,0x23,0x22,0x26,0x35,0x34,0x36,0x01,0x53,0x56,0x7b,0x7a,0x57,0x57,0x78,0x79,0x56,0x73,0xa2,0xa4,0x73,0x75,0xa0,0xa3,0x05,0x5c,0x7a,0x57,0x57,0x78,0x78,0x57,0x57,0x7a,0x46,0xa3,0x73,0x72,0xa4,0xa2,0x74,0x74,0xa2,0x00,0x01,0x00,0x28,0xff,0xf6,0x04,0x48,0x05,0xb7,0x00,0x20,0x00,0x00,0x01,0x04,0x13,0x14,0x02,0x05,0x25,0x32,0x16,0x17,0x14,0x23,0x26,0x27,0x04,0x07,0x26,0x35,0x36,0x25,0x24,0x11,0x02,0x25,0x04,0x03,0x06,0x23,0x22,0x27,0x37,0x12,0x25,0x02,0x5c,0x01,0x9b,0x35,0xfa,0xfe,0x7c,0x01,0x0e,0x91,0xf5,0x06,0x6f,0x44,0xd5,0xfe,0x69,0x6f,0x67,0x01,0x01,0x83,0x01,0x9c,0x18,0xfe,0xd9,0xfe,0xf4,0x4c,0x0a,0x5d,0x4c,0x01,0x02,0x44,0x01,0x9a,0x05,0xb7,0x2b,0xfe,0x62,0xe5,0xfe,0xb2,0xe9,0x12,0x30,0x62,0x57,0x19,0x0c,0x11,0x19,0x0a,0x6b,0x6a,0xfc,0xf1,0x01,0x1f,0x01,0x13,0x19,0x0a,0xfe,0xee,0x74,0x6a,0x1f,0x01,0x83,0x2e,0x00,0x00,0x00,0x01,0x00,0x20,0xff,0xf7,0x04,0x57,0x05,0xc5,0x00,0x27,0x00,0x00,0x01,0x04,0x1f,0x01,0x06,0x07,0x04,0x13,0x02,0x05,0x24,0x03,0x36,0x33,0x32,0x12,0x17,0x24,0x37,0x02,0x25,0x06,0x07,0x26,0x35,0x36,0x37,0x36,0x35,0x26,0x27,0x04,0x07,0x14,0x07,0x26,0x27,0x37,0x12,0x25,0x02,0x69,0x01,0x1c,0x3d,0x0a,0x08,0x87,0x01,0x15,0x05,0x33,0xfe,0x16,0xfe,0x00,0x1a,0x0e,0x54,0x42,0x62,0xfb,0x01,0x49,0x23,0x13,0xfe,0xfd,0x5e,0x6c,0x61,0x0b,0xd0,0xcb,0x11,0x86,0xfe,0xbd,0x32,0x5e,0x4c,0x09,0x01,0x49,0x01,0x8f,0x05,0xc5,0x18,0xee,0x3c,0x9e,0x74,0x55,0xfe,0xab,0xfe,0x5d,0x2d,0x04,0x01,0x98,0x47,0xfe,0xfe,0x14,0x0e,0xfb,0x01,0x14,0x0e,0x07,0x07,0x14,0x54,0x5d,0x19,0x18,0xc1,0x72,0x07,0x07,0xc7,0x46,0x0a,0x14,0x55,0x32,0x01,0x20,0x15,0x00,0x00,0x00,0x00,0x01,0x00,0xd3,0x04,0xf2,0x02,0xef,0x06,0x00,0x00,0x0c,0x00,0x00,0x00,0x17,0x14,0x07,0x04,0x23,0x26,0x27,0x34,0x37,0x3e,0x01,0x37,0x02,0xed,0x02,0x54,0xfe,0xab,0x36,0x3c,0x01,0x54,0x9d,0xd9,0x21,0x05,0xf6,0x2c,0x2e,0x1b,0x8f,0x01,0x32,0x31,0x16,0x3b,0x58,0x01,0x00,0x00,0x00,0x00,0x01,0x00,0x9e,0x02,0xa0,0x01,0x7b,0x03,0x83,0x00,0x07,0x00,0x00,0x12,0x37,0x32,0x17,0x14,0x07,0x26,0x27,0x9f,0x64,0x6f,0x09,0x69,0x6c,0x08,0x03,0x7b,0x08,0x6c,0x74,0x03,0x01,0x68,0x00,0x00,0x00,0x00,0x01,0x01,0x58,0xfe,0x3c,0x02,0xe9,0x00,0x08,0x00,0x15,0x00,0x00,0x25,0x33,0x14,0x17,0x16,0x17,0x06,0x07,0x26,0x27,0x36,0x33,0x32,0x16,0x17,0x36,0x37,0x26,0x27,0x26,0x27,0x26,0x01,0xb3,0x6f,0x43,0x82,0x02,0x14,0xac,0xc7,0x0a,0x04,0x31,0x1e,0x29,0x4b,0x50,0x0e,0x07,0x51,0x32,0x27,0x19,0x08,0x67,0x04,0x33,0x80,0x9d,0x11,0x01,0x99,0x2f,0x59,0x08,0x05,0x43,0x4c,0x05,0x0b,0x30,0x21,0x00,0x00,0x00,0x00,0x01,0x00,0xbd,0x00,0x00,0x03,0x27,0x05,0xc1,0x00,0x12,0x00,0x00,0x00,0x17,0x02,0x03,0x06,0x23,0x26,0x27,0x12,0x11,0x06,0x07,0x26,0x27,0x34,0x3f,0x01,0x36,0x33,0x03,0x12,0x15,0x05,0x29,0x09,0x5e,0x57,0x11,0x37,0xe3,0x66,0x48,0x13,0x2f,0xe4,0x8b,0x59,0x05,0xb7,0x40,0xfe,0x08,0xfc,0xc4,0x43,0x03,0x3e,0x03,0x3d,0x01,0x51,0xf9,0x0c,0x07,0x3d,0x48,0x25,0xba,0x8c,0x00,0x00,0x00,0x00,0x04,0x00,0x1b,0xff,0xee,0x06,0x8a,0x05,0xee,0x00,0x12,0x00,0x1d,0x00,0x35,0x00,0x3b,0x00,0x00,0x00,0x17,0x02,0x03,0x06,0x23,0x26,0x27,0x12,0x35,0x06,0x07,0x26,0x27,0x34,0x3f,0x01,0x36,0x33,0x25,0x16,0x17,0x06,0x01,0x26,0x3d,0x01,0x36,0x01,0x36,0x01,0x32,0x17,0x02,0x03,0x37,0x16,0x17,0x06,0x23,0x27,0x17,0x06,0x23,0x26,0x27,0x37,0x06,0x07,0x26,0x3d,0x01,0x36,0x00,0x17,0x00,0x07,0x36,0x37,0x12,0x01,0xa4,0x0e,0x03,0x1b,0x06,0x3e,0x39,0x0c,0x25,0x96,0x43,0x2f,0x0d,0x1f,0x96,0x5c,0x3a,0x02,0x9b,0x36,0x06,0x03,0xfd,0xcc,0x53,0x02,0x02,0x12,0x06,0x01,0xaf,0x44,0x22,0x02,0x18,0x72,0x42,0x0e,0x15,0x25,0x88,0x03,0x0b,0x3b,0x3a,0x07,0x06,0xc5,0xc5,0x45,0x1a,0x01,0xb3,0x1e,0xfe,0xad,0x06,0x93,0xac,0x18,0x05,0xb0,0x2a,0xfe,0xb1,0xfd,0xda,0x2c,0x02,0x29,0x02,0x27,0xdf,0xa5,0x08,0x05,0x28,0x30,0x19,0x7b,0x5d,0x37,0x04,0x65,0x5a,0xfa,0xc3,0x03,0x50,0x21,0x40,0x05,0x06,0x3d,0xfd,0xfc,0x47,0xfe,0xff,0xfe,0xc2,0x07,0x06,0x3e,0x47,0x05,0xa9,0x2b,0x05,0x3d,0x8c,0x01,0x23,0x0a,0x5a,0x1b,0xc7,0x01,0xe9,0x9d,0xfe,0xae,0xb9,0x1e,0x01,0x01,0x49,0x00,0x03,0x00,0x1a,0xff,0xee,0x06,0x40,0x05,0xee,0x00,0x12,0x00,0x1d,0x00,0x3e,0x00,0x00,0x00,0x17,0x02,0x03,0x06,0x23,0x26,0x27,0x12,0x35,0x06,0x07,0x26,0x27,0x34,0x3f,0x01,0x36,0x33,0x25,0x16,0x17,0x06,0x01,0x26,0x3d,0x01,0x36,0x01,0x36,0x01,0x16,0x13,0x14,0x06,0x07,0x37,0x32,0x16,0x17,0x14,0x07,0x26,0x27,0x04,0x07,0x27,0x22,0x27,0x36,0x37,0x24,0x35,0x26,0x27,0x06,0x07,0x14,0x23,0x22,0x27,0x36,0x25,0x01,0xa3,0x0e,0x03,0x1b,0x06,0x3e,0x39,0x0c,0x25,0x96,0x43,0x2f,0x0d,0x1f,0x96,0x5c,0x3a,0x02,0x4c,0x36,0x06,0x03,0xfd,0xcc,0x53,0x02,0x02,0x12,0x06,0x01,0x82,0xff,0x30,0xa3,0xfd,0xb0,0x5e,0xa0,0x04,0x48,0x2d,0x84,0xfe,0xf0,0x3b,0x2b,0x18,0x0d,0x01,0xfc,0x01,0x13,0x1b,0xc0,0xaf,0x47,0x43,0x2a,0x08,0x2e,0x01,0x25,0x05,0xab,0x2a,0xfe,0xb1,0xfd,0xda,0x2c,0x02,0x29,0x02,0x27,0xdf,0xa5,0x08,0x05,0x28,0x30,0x19,0x7b,0x5d,0x3c,0x04,0x65,0x5a,0xfa,0xc3,0x03,0x50,0x21,0x40,0x05,0x06,0x3d,0xfd,0xd7,0x1c,0xfe,0xf3,0x88,0xe6,0x98,0x05,0x18,0x40,0x2c,0x0d,0x11,0x07,0x04,0x17,0x07,0x4c,0x31,0xaa,0x9d,0xbb,0xb3,0x10,0x07,0xab,0x4c,0x52,0xf0,0x31,0x00,0x00,0x00,0x00,0x04,0x00,0x20,0xff,0xd5,0x06,0x8a,0x05,0xd5,0x00,0x27,0x00,0x3f,0x00,0x45,0x00,0x50,0x00,0x00,0x01,0x16,0x1f,0x01,0x06,0x07,0x16,0x17,0x02,0x05,0x24,0x03,0x36,0x33,0x32,0x16,0x17,0x36,0x37,0x26,0x27,0x06,0x07,0x26,0x35,0x36,0x37,0x36,0x35,0x26,0x27,0x06,0x07,0x14,0x07,0x26,0x27,0x35,0x36,0x25,0x01,0x32,0x17,0x02,0x03,0x37,0x16,0x17,0x06,0x23,0x27,0x17,0x06,0x23,0x26,0x27,0x37,0x06,0x07,0x26,0x3d,0x01,0x36,0x00,0x17,0x00,0x07,0x36,0x37,0x12,0x03,0x16,0x17,0x06,0x01,0x26,0x3d,0x01,0x36,0x01,0x36,0x01,0xb4,0xc5,0x2a,0x07,0x06,0x5d,0xc0,0x03,0x23,0xfe,0xad,0xfe,0x9e,0x12,0x18,0x33,0x26,0x44,0xae,0xe3,0x18,0x0d,0xb3,0x41,0x4b,0x43,0x08,0x90,0x8c,0x0c,0x5c,0xe0,0x22,0x41,0x35,0x05,0x32,0x01,0x14,0x04,0x08,0x44,0x22,0x02,0x18,0x72,0x42,0x0e,0x15,0x25,0x88,0x03,0x0b,0x3b,0x3a,0x07,0x06,0xc5,0xc5,0x45,0x1a,0x01,0xb3,0x1e,0xfe,0xad,0x06,0x93,0xac,0x18,0xe4,0x36,0x06,0x03,0xfd,0xcc,0x53,0x02,0x02,0x12,0x06,0x05,0xc5,0x10,0x9c,0x28,0x68,0x4c,0x38,0xe0,0xfe,0xed,0x1e,0x03,0x01,0x0c,0x2f,0xaa,0x0d,0x09,0xa5,0xb5,0x0a,0x05,0x05,0x0e,0x37,0x3d,0x10,0x10,0x7f,0x4b,0x05,0x05,0x83,0x27,0x0d,0x0d,0x31,0x28,0xbd,0x0e,0xfe,0x1d,0x47,0xfe,0xff,0xfe,0xc2,0x07,0x06,0x3e,0x47,0x05,0xa9,0x2b,0x05,0x3d,0x8c,0x01,0x23,0x0a,0x5a,0x1b,0xc7,0x01,0xe9,0x9d,0xfe,0xae,0xb9,0x1e,0x01,0x01,0x49,0x03,0x34,0x04,0x65,0x5a,0xfa,0xc3,0x03,0x50,0x21,0x40,0x05,0x06,0x3d,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x02,0x1e,0x00,0x01,0x00,0x58,0x01,0x80,0x00,0x06,0x00,0x90,0x00,0x24,0x00,0x37,0xff,0x92,0x00,0x24,0x00,0x3a,0x00,0x6c,0x00,0x24,0x00,0x3c,0xff,0x92,0x00,0x24,0x00,0x59,0x00,0xa0,0x00,0x24,0x00,0x5a,0x00,0xa8,0x00,0x24,0x00,0x5c,0x00,0x5d,0x00,0x29,0x00,0x0f,0xfc,0x7f,0x00,0x29,0x00,0x11,0xfc,0x46,0x00,0x29,0x00,0x24,0x00,0x7e,0x00,0x2f,0x00,0x37,0xfe,0x7e,0x00,0x2f,0x00,0x39,0xfe,0x6a,0x00,0x2f,0x00,0x3a,0xfe,0x66,0x00,0x2f,0x00,0x3c,0xfe,0x47,0x00,0x2f,0x00,0x5c,0x00,0xa3,0x00,0x33,0x00,0x0f,0xfb,0x61,0x00,0x33,0x00,0x11,0xfb,0x28,0x00,0x33,0x00,0x24,0x00,0x62,0x00,0x35,0x00,0x37,0xff,0x3f,0x00,0x35,0x00,0x39,0xff,0xbc,0x00,0x35,0x00,0x3a,0xff,0xbc,0x00,0x35,0x00,0x3c,0xff,0x7d,0x00,0x37,0x00,0x0f,0xfd,0xa3,0x00,0x37,0x00,0x10,0xfe,0x51,0x00,0x37,0x00,0x11,0xfd,0x6a,0x00,0x37,0x00,0x1d,0xfd,0x6a,0x00,0x37,0x00,0x1e,0xfd,0x6a,0x00,0x37,0x00,0x24,0x00,0x36,0x00,0x37,0x00,0x32,0xff,0x28,0x00,0x37,0x00,0x44,0xfd,0xf4,0x00,0x37,0x00,0x46,0xfd,0xdc,0x00,0x37,0x00,0x48,0xfd,0xd5,0x00,0x37,0x00,0x4c,0x00,0x47,0x00,0x37,0x00,0x52,0xfd,0xda,0x00,0x37,0x00,0x55,0xfd,0xd4,0x00,0x37,0x00,0x56,0xfd,0xff,0x00,0x37,0x00,0x58,0xfd,0xe9,0x00,0x37,0x00,0x5a,0xfd,0xdf,0x00,0x37,0x00,0x5c,0xfd,0xdc,0x00,0x39,0x00,0x0f,0xfd,0xd6,0x00,0x39,0x00,0x10,0xff,0x37,0x00,0x39,0x00,0x11,0xfd,0x9d,0x00,0x39,0x00,0x1d,0xff,0x0b,0x00,0x39,0x00,0x1e,0xff,0x0b,0x00,0x39,0x00,0x24,0x00,0x7a,0x00,0x39,0x00,0x44,0xff,0x23,0x00,0x39,0x00,0x48,0xff,0x10,0x00,0x39,0x00,0x4c,0x00,0x34,0x00,0x39,0x00,0x52,0xfe,0xfe,0x00,0x39,0x00,0x55,0xff,0x80,0x00,0x39,0x00,0x58,0xff,0x7d,0x00,0x39,0x00,0x5c,0xff,0x8b,0x00,0x3a,0x00,0x0f,0xfd,0xae,0x00,0x3a,0x00,0x10,0xff,0x34,0x00,0x3a,0x00,0x11,0xfd,0xae,0x00,0x3a,0x00,0x1d,0xff,0x09,0x00,0x3a,0x00,0x1e,0xff,0x09,0x00,0x3a,0x00,0x24,0x00,0x5e,0x00,0x3a,0x00,0x44,0xff,0x13,0x00,0x3a,0x00,0x48,0xff,0x0e,0x00,0x3a,0x00,0x4c,0x00,0x32,0x00,0x3a,0x00,0x52,0xff,0x2f,0x00,0x3a,0x00,0x55,0xff,0x7e,0x00,0x3a,0x00,0x58,0xff,0x7b,0x00,0x3a,0x00,0x5c,0xff,0x89,0x00,0x3c,0x00,0x0f,0xfd,0x95,0x00,0x3c,0x00,0x10,0xfe,0x7e,0x00,0x3c,0x00,0x11,0xfd,0x95,0x00,0x3c,0x00,0x1d,0xfe,0xb1,0x00,0x3c,0x00,0x1e,0xfe,0xb1,0x00,0x3c,0x00,0x24,0x00,0x76,0x00,0x3c,0x00,0x44,0xfe,0x9b,0x00,0x3c,0x00,0x48,0xfe,0x77,0x00,0x3c,0x00,0x4c,0x00,0x56,0x00,0x3c,0x00,0x52,0xfe,0x98,0x00,0x3c,0x00,0x53,0xff,0x1e,0x00,0x3c,0x00,0x54,0xfe,0x40,0x00,0x3c,0x00,0x58,0xff,0x22,0x00,0x3c,0x00,0x59,0xff,0x47,0x00,0x49,0x00,0x48,0xff,0x55,0x00,0x49,0x00,0x49,0x00,0xee,0x00,0x55,0x00,0x0f,0xfe,0x80,0x00,0x55,0x00,0x11,0xfe,0x47,0x00,0x59,0x00,0x0f,0xfe,0x9d,0x00,0x59,0x00,0x11,0xfe,0x64,0x00,0x5a,0x00,0x0f,0xff,0x15,0x00,0x5a,0x00,0x11,0xff,0x21,0x00,0x5c,0x00,0x0f,0xff,0xce,0x00,0x5c,0x00,0x11,0xff,0xce,0x00,0x00,0x00,0x00,0x00,0x2a,0x01,0xfe,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x09,0x00,0x3b,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x07,0x00,0x34,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x16,0x00,0x3b,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x09,0x00,0x3b,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x2c,0x00,0x51,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x08,0x00,0x7d,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x09,0x00,0x0d,0x00,0x85,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x0a,0x00,0x3f,0x00,0x92,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x0c,0x00,0x19,0x00,0xd1,0x00,0x03,0x00,0x01,0x04,0x03,0x00,0x02,0x00,0x0c,0x03,0x16,0x00,0x03,0x00,0x01,0x04,0x05,0x00,0x02,0x00,0x10,0x00,0xea,0x00,0x03,0x00,0x01,0x04,0x06,0x00,0x02,0x00,0x0c,0x00,0xfa,0x00,0x03,0x00,0x01,0x04,0x07,0x00,0x02,0x00,0x10,0x01,0x06,0x00,0x03,0x00,0x01,0x04,0x08,0x00,0x02,0x00,0x10,0x01,0x16,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x00,0x00,0x96,0x01,0x26,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x01,0x00,0x16,0x01,0x26,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x02,0x00,0x0e,0x01,0xbc,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x03,0x00,0x30,0x01,0xca,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x04,0x00,0x16,0x01,0x26,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x05,0x00,0x6e,0x01,0xfa,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x09,0x00,0x1a,0x01,0x44,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x0a,0x00,0x7e,0x02,0x68,0x00,0x03,0x00,0x01,0x04,0x0a,0x00,0x02,0x00,0x0c,0x03,0x16,0x00,0x03,0x00,0x01,0x04,0x0b,0x00,0x02,0x00,0x10,0x02,0xe6,0x00,0x03,0x00,0x01,0x04,0x0c,0x00,0x02,0x00,0x0c,0x03,0x16,0x00,0x03,0x00,0x01,0x04,0x0e,0x00,0x02,0x00,0x0c,0x03,0x34,0x00,0x03,0x00,0x01,0x04,0x10,0x00,0x02,0x00,0x0e,0x02,0xf6,0x00,0x03,0x00,0x01,0x04,0x13,0x00,0x02,0x00,0x12,0x03,0x04,0x00,0x03,0x00,0x01,0x04,0x14,0x00,0x02,0x00,0x0c,0x03,0x16,0x00,0x03,0x00,0x01,0x04,0x15,0x00,0x02,0x00,0x10,0x03,0x16,0x00,0x03,0x00,0x01,0x04,0x16,0x00,0x02,0x00,0x0c,0x03,0x16,0x00,0x03,0x00,0x01,0x04,0x19,0x00,0x02,0x00,0x0e,0x03,0x26,0x00,0x03,0x00,0x01,0x04,0x1b,0x00,0x02,0x00,0x10,0x03,0x34,0x00,0x03,0x00,0x01,0x04,0x1d,0x00,0x02,0x00,0x0c,0x03,0x16,0x00,0x03,0x00,0x01,0x04,0x1f,0x00,0x02,0x00,0x0c,0x03,0x16,0x00,0x03,0x00,0x01,0x04,0x24,0x00,0x02,0x00,0x0e,0x03,0x44,0x00,0x03,0x00,0x01,0x04,0x2d,0x00,0x02,0x00,0x0e,0x03,0x52,0x00,0x03,0x00,0x01,0x08,0x0a,0x00,0x02,0x00,0x0c,0x03,0x16,0x00,0x03,0x00,0x01,0x08,0x16,0x00,0x02,0x00,0x0c,0x03,0x16,0x00,0x03,0x00,0x01,0x0c,0x0a,0x00,0x02,0x00,0x0c,0x03,0x16,0x00,0x03,0x00,0x01,0x0c,0x0c,0x00,0x02,0x00,0x0c,0x03,0x16,0x54,0x79,0x70,0x65,0x66,0x61,0x63,0x65,0x20,0xa9,0x20,0x28,0x79,0x6f,0x75,0x72,0x20,0x63,0x6f,0x6d,0x70,0x61,0x6e,0x79,0x29,0x2e,0x20,0x32,0x30,0x30,0x38,0x2e,0x20,0x41,0x6c,0x6c,0x20,0x52,0x69,0x67,0x68,0x74,0x73,0x20,0x52,0x65,0x73,0x65,0x72,0x76,0x65,0x64,0x52,0x65,0x67,0x75,0x6c,0x61,0x72,0x51,0x69,0x6b,0x6b,0x69,0x20,0x52,0x65,0x67,0x3a,0x56,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x31,0x2e,0x30,0x30,0x56,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x31,0x2e,0x30,0x30,0x20,0x4d,0x61,0x72,0x63,0x68,0x20,0x32,0x36,0x2c,0x20,0x32,0x30,0x30,0x38,0x2c,0x20,0x69,0x6e,0x69,0x74,0x69,0x61,0x6c,0x20,0x72,0x65,0x6c,0x65,0x61,0x73,0x65,0x51,0x69,0x6b,0x6b,0x69,0x52,0x65,0x67,0x4a,0x6f,0x61,0x6e,0x6e,0x65,0x20,0x54,0x61,0x79,0x6c,0x6f,0x72,0x54,0x68,0x69,0x73,0x20,0x66,0x6f,0x6e,0x74,0x20,0x77,0x61,0x73,0x20,0x63,0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x75,0x73,0x69,0x6e,0x67,0x20,0x46,0x6f,0x6e,0x74,0x43,0x72,0x65,0x61,0x74,0x6f,0x72,0x20,0x35,0x2e,0x36,0x20,0x66,0x72,0x6f,0x6d,0x20,0x48,0x69,0x67,0x68,0x2d,0x4c,0x6f,0x67,0x69,0x63,0x2e,0x63,0x6f,0x6d,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x61,0x72,0x74,0x2d,0x6f,0x66,0x2d,0x71,0x2e,0x63,0x6f,0x2e,0x7a,0x61,0x00,0x6f,0x00,0x62,0x00,0x79,0x01,0x0d,0x00,0x65,0x00,0x6a,0x00,0x6e,0x00,0xe9,0x00,0x6e,0x00,0x6f,0x00,0x72,0x00,0x6d,0x00,0x61,0x00,0x6c,0x00,0x53,0x00,0x74,0x00,0x61,0x00,0x6e,0x00,0x64,0x00,0x61,0x00,0x72,0x00,0x64,0x03,0x9a,0x03,0xb1,0x03,0xbd,0x03,0xbf,0x03,0xbd,0x03,0xb9,0x03,0xba,0x03,0xac,0x00,0x51,0x00,0x61,0x00,0x72,0x00,0x6d,0x00,0x69,0x00,0x63,0x00,0x20,0x00,0x73,0x00,0x61,0x00,0x6e,0x00,0x73,0x00,0x20,0x00,0xa9,0x00,0x20,0x00,0x28,0x00,0x4a,0x00,0x6f,0x00,0x61,0x00,0x6e,0x00,0x6e,0x00,0x65,0x00,0x20,0x00,0x54,0x00,0x61,0x00,0x79,0x00,0x6c,0x00,0x6f,0x00,0x72,0x00,0x20,0x00,0x2d,0x00,0x20,0x00,0x71,0x00,0x61,0x00,0x62,0x00,0x62,0x00,0x6f,0x00,0x6a,0x00,0x6f,0x00,0x40,0x00,0x79,0x00,0x61,0x00,0x68,0x00,0x6f,0x00,0x6f,0x00,0x2e,0x00,0x63,0x00,0x6f,0x00,0x6d,0x00,0x29,0x00,0x20,0x00,0x32,0x00,0x30,0x00,0x30,0x00,0x39,0x00,0x2e,0x00,0x20,0x00,0x41,0x00,0x6c,0x00,0x6c,0x00,0x20,0x00,0x52,0x00,0x69,0x00,0x67,0x00,0x68,0x00,0x74,0x00,0x73,0x00,0x20,0x00,0x52,0x00,0x65,0x00,0x73,0x00,0x65,0x00,0x72,0x00,0x76,0x00,0x65,0x00,0x64,0x00,0x52,0x00,0x65,0x00,0x67,0x00,0x75,0x00,0x6c,0x00,0x61,0x00,0x72,0x00,0x51,0x00,0x61,0x00,0x72,0x00,0x6d,0x00,0x69,0x00,0x63,0x00,0x20,0x00,0x73,0x00,0x61,0x00,0x6e,0x00,0x73,0x00,0x3a,0x00,0x56,0x00,0x65,0x00,0x72,0x00,0x73,0x00,0x69,0x00,0x6f,0x00,0x6e,0x00,0x20,0x00,0x31,0x00,0x2e,0x00,0x30,0x00,0x30,0x00,0x51,0x00,0x61,0x00,0x72,0x00,0x6d,0x00,0x69,0x00,0x63,0x00,0x20,0x00,0x73,0x00,0x61,0x00,0x6e,0x00,0x73,0x00,0x20,0x00,0x56,0x00,0x65,0x00,0x72,0x00,0x73,0x00,0x69,0x00,0x6f,0x00,0x6e,0x00,0x20,0x00,0x31,0x00,0x2e,0x00,0x30,0x00,0x30,0x00,0x3b,0x00,0x20,0x00,0x46,0x00,0x65,0x00,0x62,0x00,0x72,0x00,0x75,0x00,0x61,0x00,0x72,0x00,0x79,0x00,0x20,0x00,0x32,0x00,0x30,0x00,0x30,0x00,0x39,0x00,0x20,0x00,0x69,0x00,0x6e,0x00,0x69,0x00,0x74,0x00,0x69,0x00,0x61,0x00,0x6c,0x00,0x20,0x00,0x72,0x00,0x65,0x00,0x6c,0x00,0x65,0x00,0x61,0x00,0x73,0x00,0x65,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x66,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00,0x20,0x00,0x77,0x00,0x61,0x00,0x73,0x00,0x20,0x00,0x63,0x00,0x72,0x00,0x65,0x00,0x61,0x00,0x74,0x00,0x65,0x00,0x64,0x00,0x20,0x00,0x75,0x00,0x73,0x00,0x69,0x00,0x6e,0x00,0x67,0x00,0x20,0x00,0x46,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00,0x43,0x00,0x72,0x00,0x65,0x00,0x61,0x00,0x74,0x00,0x6f,0x00,0x72,0x00,0x20,0x00,0x35,0x00,0x2e,0x00,0x36,0x00,0x20,0x00,0x66,0x00,0x72,0x00,0x6f,0x00,0x6d,0x00,0x20,0x00,0x48,0x00,0x69,0x00,0x67,0x00,0x68,0x00,0x2d,0x00,0x4c,0x00,0x6f,0x00,0x67,0x00,0x69,0x00,0x63,0x00,0x2e,0x00,0x63,0x00,0x6f,0x00,0x6d,0x00,0x4e,0x00,0x6f,0x00,0x72,0x00,0x6d,0x00,0x61,0x00,0x61,0x00,0x6c,0x00,0x69,0x00,0x4e,0x00,0x6f,0x00,0x72,0x00,0x6d,0x00,0x61,0x00,0x6c,0x00,0x65,0x00,0x53,0x00,0x74,0x00,0x61,0x00,0x6e,0x00,0x64,0x00,0x61,0x00,0x61,0x00,0x72,0x00,0x64,0x00,0x4e,0x00,0x6f,0x00,0x72,0x00,0x6d,0x00,0x61,0x00,0x6c,0x00,0x6e,0x00,0x79,0x04,0x1e,0x04,0x31,0x04,0x4b,0x04,0x47,0x04,0x3d,0x04,0x4b,0x04,0x39,0x00,0x4e,0x00,0x6f,0x00,0x72,0x00,0x6d,0x00,0xe1,0x00,0x6c,0x00,0x6e,0x00,0x65,0x00,0x4e,0x00,0x61,0x00,0x76,0x00,0x61,0x00,0x64,0x00,0x6e,0x00,0x6f,0x00,0x41,0x00,0x72,0x00,0x72,0x00,0x75,0x00,0x6e,0x00,0x74,0x00,0x61,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x27,0x00,0x96,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x01,0x00,0x02,0x00,0x03,0x00,0x04,0x00,0x05,0x00,0x06,0x00,0x07,0x00,0x08,0x00,0x09,0x00,0x0a,0x00,0x0b,0x00,0x0c,0x00,0x0d,0x00,0x0e,0x00,0x0f,0x00,0x10,0x00,0x11,0x00,0x12,0x00,0x13,0x00,0x14,0x00,0x15,0x00,0x16,0x00,0x17,0x00,0x18,0x00,0x19,0x00,0x1a,0x00,0x1b,0x00,0x1c,0x00,0x1d,0x00,0x1e,0x00,0x1f,0x00,0x20,0x00,0x21,0x00,0x22,0x00,0x23,0x00,0x24,0x00,0x25,0x00,0x26,0x00,0x27,0x00,0x28,0x00,0x29,0x00,0x2a,0x00,0x2b,0x00,0x2c,0x00,0x2d,0x00,0x2e,0x00,0x2f,0x00,0x30,0x00,0x31,0x00,0x32,0x00,0x33,0x00,0x34,0x00,0x35,0x00,0x36,0x00,0x37,0x00,0x38,0x00,0x39,0x00,0x3a,0x00,0x3b,0x00,0x3c,0x00,0x3d,0x00,0x3e,0x00,0x3f,0x00,0x40,0x00,0x41,0x00,0x42,0x00,0x43,0x00,0x44,0x00,0x45,0x00,0x46,0x00,0x47,0x00,0x48,0x00,0x49,0x00,0x4a,0x00,0x4b,0x00,0x4c,0x00,0x4d,0x00,0x4e,0x00,0x4f,0x00,0x50,0x00,0x51,0x00,0x52,0x00,0x53,0x00,0x54,0x00,0x55,0x00,0x56,0x00,0x57,0x00,0x58,0x00,0x59,0x00,0x5a,0x00,0x5b,0x00,0x5c,0x00,0x5d,0x00,0x61,0x00,0xa3,0x00,0x84,0x00,0x85,0x00,0x8e,0x00,0x9d,0x00,0xa4,0x00,0xda,0x00,0x83,0x01,0x02,0x01,0x03,0x00,0x8d,0x00,0xc3,0x00,0xde,0x01,0x04,0x00,0xf5,0x00,0xf4,0x00,0xf6,0x07,0x75,0x6e,0x69,0x30,0x30,0x42,0x32,0x07,0x75,0x6e,0x69,0x30,0x30,0x42,0x33,0x07,0x75,0x6e,0x69,0x30,0x30,0x42,0x39,0x00,0x00,0x00,0x00,0x00,0x01,0xff,0xff,0x00,0x02 +] +)