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 0000000000..0ce68b728d Binary files /dev/null and b/examples/ttf_font/Graduate-Regular.ttf differ diff --git a/examples/ttf_font/Imprima-Regular.ttf b/examples/ttf_font/Imprima-Regular.ttf new file mode 100644 index 0000000000..9c701e12d3 Binary files /dev/null and b/examples/ttf_font/Imprima-Regular.ttf differ diff --git a/examples/ttf_font/OFL.txt b/examples/ttf_font/OFL.txt new file mode 100644 index 0000000000..3a5f6c1ba7 --- /dev/null +++ b/examples/ttf_font/OFL.txt @@ -0,0 +1,93 @@ +Copyright (c) 2012, Eduardo Tunni (http://www.tipo.net.ar), with Reserved Font Name "Imprima" + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/examples/ttf_font/example_ttf.v b/examples/ttf_font/example_ttf.v new file mode 100644 index 0000000000..31132b35fb --- /dev/null +++ b/examples/ttf_font/example_ttf.v @@ -0,0 +1,202 @@ +import gg +import gx +import sokol.sapp +import sokol.sgl + +import x.ttf +import os +//import math + +const ( + win_width = 600 + win_height = 700 + bg_color = gx.white + font_paths = [ + "Imprima-Regular.ttf" + "Graduate-Regular.ttf" + ] +) + +/****************************************************************************** +* +* UI +* +*****************************************************************************/ +struct App_data { +pub mut: + gg &gg.Context + sg_img C.sg_image + init_flag bool + frame_c int + + tf []ttf.TTF_File + ttf_render []ttf.TTF_render_Sokol + text_ready_flag bool + + mouse_x int = -1 + mouse_y int = -1 +} + +fn my_init(mut app App_data) { + app.init_flag = true +} + +fn draw_frame(mut app &App_data) { + cframe_txt := "Current Frame: $app.frame_c" + + app.gg.begin() + + sgl.defaults() + sgl.matrix_mode_projection() + sgl.ortho(0.0, f32(sapp.width()), f32(sapp.height()), 0.0, -1.0, 1.0) + sgl.c4b(0, 0, 0, 255) // black + + // draw a line as background + sgl.begin_line_strip() + sgl.v2f(10, 10) + sgl.v2f(100, 100) + sgl.end() + + // draw text only if the app is already initialized + if app.init_flag == true { + sgl.begin_line_strip() + sgl.v2f(410, 400) + sgl.v2f(510, 400) + sgl.end() + + // update the text + mut txt1 := &app.ttf_render[0] + if app.frame_c % 2 == 0 { + txt1.destroy_texture() + txt1.create_text(cframe_txt ,43) + txt1.create_texture() + } + + // ----- decomment if you want text rotation ---- + //txt1.bmp.angle = 3.141592 / 180 * f32(app.frame_c % 360) + //txt1.draw_text_bmp(app.gg, 300, 350) + //txt1.bmp.angle = 0 + + txt1.draw_text_bmp(app.gg, 30, 60) + + // block test + block_txt := "Today it is a good day! +Tommorow I'm not so sure :( +Frame: $app.frame_c +But Vwill prevail for sure, V is the way!! +òàèì@ò!£$%& +" + txt1 = &app.ttf_render[1] + if app.frame_c % 2 == 0 { + + txt1.bmp.justify = false + if (app.frame_c>>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 +] +)