diff --git a/arch/arm64/boot/dts/amlogic/khadas-ts050-panel.dtsi b/arch/arm64/boot/dts/amlogic/khadas-ts050-panel.dtsi index f7046fb0cfd8c..22bf43164e703 100644 --- a/arch/arm64/boot/dts/amlogic/khadas-ts050-panel.dtsi +++ b/arch/arm64/boot/dts/amlogic/khadas-ts050-panel.dtsi @@ -634,8 +634,154 @@ 0xff 0 0 0>; backlight_index = <0>; }; + + lcd_1{ + model_name = "TS050"; + interface = "mipi"; + basic_setting = <1088 1920 /*h_active, v_active*/ + 1140 1940/*h_period, v_period */ + 8 /*lcd_bits*/ + 64 118>; /*screen_widht, screen_height*/ + lcd_timing = <6 30 0 /*hs_width,hs_bp,hs_pol*/ + 6 10 0>; /*vs_width,vs_bp,vs_pol*/ + clk_attr = <0 /*fr_adj_type(0=clock,1=htotal,2=vtotal)*/ + 0 /*clk_ss_level*/ + 1 /*clk_auto_generate*/ + 120000000>; /*pixel_clk(unit in Hz)*/ + mipi_attr = <4 /*lane_num*/ + 1000 /*bit_rate_max(MHz) */ + 0 /*factor(*100, default 0 for auto)*/ + 1 /*operation_mode_init(0=video, 1=command)*/ + 0 /*operation_mode_display(0=video, 1=command)*/ + 2 /* + *video_mode_type + *(0=sync_pulse,1=sync_event,2=burst) + */ + 1 /*clk_always_hs(0=disable,1=enable)*/ + 0>; /*phy_switch(0=auto,1=standard,2=slow)*/ + /* dsi_init: data_type, num, data... */ + dsi_init_on = < + 0x39 0x04 0xB9 0xFF 0x83 0x99 + 0x39 0x05 0xBA 0x63 0x23 0x68 0xCF + 0x15 0x02 0xD2 0x55 + 0x39 0x10 0xB1 0x02 0x04 0x70 0x90 0x01 0x32 0x33 0x11 0x11 0x4D 0x57 0x56 0x73 0x02 0x02 + 0x39 0x0c 0xB2 0x00 0x80 0x80 0xAE 0x0A 0x0E 0x75 0x11 0x00 0x00 0x00 + 0x39 0x2f 0xB4 0x00 0xFF 0x04 0xA4 0x02 0xA0 0x00 0x00 0x10 0x00 0x00 0x02 0x00 0x24 0x02 0x04 0x0A 0x21 0x03 0x00 0x00 0x08 0xA6 0x88 0x04 0xA4 0x02 0xA0 0x00 0x00 0x10 0x00 0x00 0x02 0x00 0x24 0x02 0x04 0x0A 0x00 0x00 0x08 0xA6 0x00 0x08 0x11 + 0x39 0x22 0xD3 0x00 0x00 0x00 0x00 0x00 0x00 0x18 0x18 0x32 0x10 0x09 0x00 0x09 0x32 0x10 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x11 0x00 0x02 0x02 0x03 0x00 0x00 0x00 0x0A 0x40 + 0x39 0x21 0xD5 0x18 0x18 0x18 0x18 0x21 0x20 0x18 0x18 0x19 0x19 0x19 0x19 0x18 0x18 0x18 0x18 0x03 0x02 0x01 0x00 0x2F 0x2F 0x30 0x30 0x31 0x31 0x18 0x18 0x18 0x18 0x18 0x18 + 0x39 0x21 0xD6 0x18 0x18 0x18 0x18 0x20 0x21 0x19 0x19 0x18 0x18 0x19 0x19 0x18 0x18 0x18 0x18 0x00 0x01 0x02 0x03 0x2F 0x2F 0x30 0x30 0x31 0x31 0x18 0x18 0x18 0x18 0x18 0x18 + 0x39 0x09 0xD8 0x0A 0xBE 0xFA 0xA0 0x0A 0xBE 0xFA 0xA0 + 0x15 0x02 0xBD 0x01 + 0x39 0x09 0xD8 0x0F 0xFF 0xFF 0xE0 0x0F 0xFF 0xFF 0xE0 + 0x15 0x02 0xBD 0x02 + 0x39 0x09 0xD8 0x0F 0xFF 0xFF 0xE0 0x0F 0xFF 0xFF 0xE0 + 0x15 0x02 0xBD 0x00 + 0x39 0x37 0xE0 0x01 0x35 0x41 0x3B 0x79 0x81 0x8C 0x85 0x8E 0x95 0x9B 0xA0 0xA4 0xAB 0xB1 0xB3 0xB7 0xC5 0xBD 0xC5 0xB6 0xC2 0xC2 0x62 0x5D 0x66 0x73 0x01 0x35 0x41 0x3B 0x79 0x81 0x8C 0x85 0x8E 0x95 0x9B 0xA0 0xA4 0xAB 0xB1 0xB3 0xB7 0xB5 0xBD 0xC5 0xB6 0xC2 0xC2 0x62 0x5D 0x66 0x73 + 0x39 0x03 0xB6 0x97 0x97 + 0x15 0x02 0xCC 0xC8 + 0x39 0x05 0xBF 0x40 0x41 0x50 0x19 + 0x39 0x03 0xC6 0xFF 0xF9 + 0x39 0x03 0xC0 0x25 0x5A + 0x05 0x01 0x11 + 0xfd 0x01 120 /* delay 120ms */ + 0x05 0x01 0x29 + 0xfd 0x01 20 /* delay 20ms */ + 0xFF 0>; /*ending*/ + dsi_init_off = < + 0x05 1 0x28 /* display off */ + 0xfd 1 10 /* delay 10ms */ + 0x05 1 0x10 /* sleep in */ + 0xfd 1 150 /* delay 150ms */ + 0xff 0>; /*ending*/ + /* extern_init: 0xff for invalid */ + extern_init = <0xff>; + /* power step: type,index,value,delay(ms) */ + power_on_step = < + 4 1 1 60 + 4 0 1 10 + 4 0 0 10 + 4 0 1 10 + 2 0 0 0 + 0xff 0 0 0>; + power_off_step = < + 2 0 0 0 + 4 0 0 0 + 4 1 0 20 + 0xff 0 0 0>; + backlight_index = <0>; + }; + + lcd_2{ + model_name = "TS101"; + interface = "mipi"; + basic_setting = <1920 1200 /*h_active, v_active*/ + 2066 1229 /*h_period, v_period*/ + 8 /*lcd_bits*/ + 154 86>; /*screen_widht, screen_height*/ + lcd_timing = <4 23 0 /*hs_width, hs_bp, hs_pol*/ + 4 14 0>; /*vs_width, vs_bp, vs_pol*/ + clk_attr = <0xff /*fr_adj_type(0=clk, 1=htotal, 2=vtotal)*/ + 0 /*clk_ss_level */ + 1 /*clk_auto_generate*/ + 137112156>; /*pixel_clk(unit in Hz)*/ + mipi_attr = <4 /*lane_num*/ + 1000 /*bit_rate_max(MHz)*/ + 0 /*factor(*100, default 0 for auto)*/ + 1 /*operation_mode_init(0=video, 1=command)*/ + 0 /*operation_mode_display(0=video, 1=command)*/ + 2 /* + *video_mode_type + *(0=sync_pulse,1=sync_event,2=burst) + */ + 1 /*clk_always_hs(0=disable,1=enable)*/ + 0>; /*phy_switch(0=auto,1=standard,2=slow)*/ + + /* dsi_init: data_type, num, data... */ + + /* dsi_init: data_type, num, data... */ + dsi_init_on = < + 0x05 1 0x11 + 0xfd 1 20 /*delay(ms)*/ + 0x05 1 0x29 + 0xfd 1 20 /*delay(ms)*/ + 0xff 0>; /*ending*/ + dsi_init_off = < + 0x05 1 0x28 + 0xfd 1 10 /*delay(ms)*/ + 0x05 1 0x10 + 0xfd 1 10 /*delay(ms)*/ + 0xff 0>; /*ending*/ + extern_init = <0xff>; /*0xff for invalid*/ + + /* power step: type, index, value, delay(ms) */ + power_on_step = < + 4 1 1 60 + 4 0 1 10 + 4 0 0 10 + 4 0 1 10 + 2 0 0 0 + 0xff 0 0 0>; /*ending*/ + power_off_step = < + 2 0 0 0 + 4 0 0 0 + 4 1 0 20 + 0xff 0 0 0>; /*ending*/ + backlight_index = <0>; + }; + + ports { + port { + #address-cells = <1>; + #size-cells = <0>; + lcd0_to_drm: endpoint@0 { + reg = <0>; + remote-endpoint = <0>; + }; + }; + }; }; + backlight: backlight{ compatible = "amlogic, backlight-g12a"; status = "okay"; diff --git a/arch/arm64/boot/dts/amlogic/kvim3_linux.dts b/arch/arm64/boot/dts/amlogic/kvim3_linux.dts index 33887a8796246..57c8ef90ceb94 100644 --- a/arch/arm64/boot/dts/amlogic/kvim3_linux.dts +++ b/arch/arm64/boot/dts/amlogic/kvim3_linux.dts @@ -883,6 +883,33 @@ status = "okay"; }; + gt9xx@5d { + compatible = "goodix,gt9xx"; + status = "okay"; + reg = <0x5d>; + reset_pin = <6>; + tp-size = <89>; + rotation = <1>; + goodix,cfg-group0 = [ + 41 80 07 B0 04 0A 3D 00 01 08 28 + 05 64 50 03 05 00 00 00 00 23 13 + 00 17 19 1C 13 90 30 AA 17 15 31 + 0D 00 00 01 9B 03 24 00 00 00 00 + 00 00 00 00 00 00 00 0F 23 94 D5 + 02 07 00 00 04 A3 10 00 8C 13 00 + 7B 16 00 69 1B 00 5B 20 00 5B 00 + 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 01 04 05 06 07 08 09 0C + 0D 0E 0F 10 11 14 15 16 17 18 19 + FF FF FF FF FF FF FF FF FF FF 00 + 02 04 06 07 08 0A 0C 0D 0E 0F 10 + 11 12 13 14 19 1B 1C 1E 1F 20 21 + 22 23 24 25 26 27 28 29 2A FF FF + FF FF FF FF FF FF FF FF 6F 01]; + }; + bq25703:bq25703@6b { compatible = "bq25703"; reg = <0x6b>; diff --git a/arch/arm64/configs/kvims_defconfig b/arch/arm64/configs/kvims_defconfig index 8db1700b6e4ef..c000016e3e1c8 100644 --- a/arch/arm64/configs/kvims_defconfig +++ b/arch/arm64/configs/kvims_defconfig @@ -526,7 +526,10 @@ CONFIG_JOYSTICK_XPAD=y CONFIG_JOYSTICK_XPAD_FF=y CONFIG_JOYSTICK_XPAD_LEDS=y CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_AMLOGIC_INPUT=y +CONFIG_AMLOGIC_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_GT9XX=y CONFIG_SENSOR_DEVICE=y CONFIG_INPUT_MISC=y CONFIG_INPUT_UINPUT=y diff --git a/drivers/amlogic/input/touchscreen/Kconfig b/drivers/amlogic/input/touchscreen/Kconfig index e0bcabfc27107..974c37f02887e 100644 --- a/drivers/amlogic/input/touchscreen/Kconfig +++ b/drivers/amlogic/input/touchscreen/Kconfig @@ -39,3 +39,13 @@ config AMLOGIC_TOUCHSCREEN_HYN_CST2XX help Say Y here if you want to use the hyn cst2xx. endif + +config TOUCHSCREEN_GT9XX + tristate "GT9XX touchscreens support" + default n + help + Say Y here to enable debug tools. + + If unsure, say N. + + To compile this driver as a module, choose M here. diff --git a/drivers/amlogic/input/touchscreen/Makefile b/drivers/amlogic/input/touchscreen/Makefile index 7352670a58707..1d837c4daff87 100644 --- a/drivers/amlogic/input/touchscreen/Makefile +++ b/drivers/amlogic/input/touchscreen/Makefile @@ -6,5 +6,5 @@ obj-$(CONFIG_AMLOGIC_TOUCHSCREEN_FTS) += focaltech_touch/ obj-$(CONFIG_AMLOGIC_TOUCHSCREEN_GT1X) += goodix_gt1x/ -obj-$(CONFIG_AMLOGIC_TOUCHSCREEN_GT9XX) += goodix_gt9xx/ +obj-$(CONFIG_AMLOGIC_TOUCHSCREEN_GT9XX) += gt9xx/ obj-$(CONFIG_AMLOGIC_TOUCHSCREEN_HYN_CST2XX) += hyn_cst2xx/ diff --git a/drivers/amlogic/input/touchscreen/gt9xx/GT9110P(2020)V71_Config_20201028_170326.cfg b/drivers/amlogic/input/touchscreen/gt9xx/GT9110P(2020)V71_Config_20201028_170326.cfg new file mode 100644 index 0000000000000..71738f447117a --- /dev/null +++ b/drivers/amlogic/input/touchscreen/gt9xx/GT9110P(2020)V71_Config_20201028_170326.cfg @@ -0,0 +1,19 @@ +0x47,0x80,0x07,0xB0,0x04,0x0A,0x7C,0x00,0x01,0x08, +0x28,0x05,0x5A,0x3C,0x03,0x04,0x00,0x00,0x08,0x00, +0x00,0x00,0x00,0x17,0x19,0x1D,0x14,0x95,0x35,0xFF, +0x3C,0x3E,0x0C,0x08,0x00,0x00,0x00,0xBA,0x02,0x2C, +0x17,0x19,0x1B,0x90,0x83,0x32,0x50,0x3C,0x28,0x4A, +0x30,0x32,0x96,0x94,0xC5,0x02,0x07,0x00,0x00,0x04, +0x83,0x38,0x00,0x79,0x45,0x00,0x71,0x57,0x00,0x6B, +0x6C,0x00,0x68,0x87,0x00,0x68,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x03, +0x00,0x48,0x21,0x10,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, +0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11, +0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B, +0x1C,0x1D,0x2A,0x29,0x28,0x27,0x26,0x25,0x24,0x23, +0x22,0x21,0x20,0x1F,0x1E,0x1D,0x1C,0x1B,0x19,0x18, +0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10,0x0F,0x0E, +0x0D,0x0C,0x0B,0x0A,0x09,0x08,0x07,0x06,0x05,0x04, +0x03,0x02,0x01,0x00,0x53,0x01 \ No newline at end of file diff --git a/drivers/amlogic/input/touchscreen/gt9xx/GT9110P_Config_20160217_1526_2048_97.cfg b/drivers/amlogic/input/touchscreen/gt9xx/GT9110P_Config_20160217_1526_2048_97.cfg new file mode 100644 index 0000000000000..952ea845390e9 --- /dev/null +++ b/drivers/amlogic/input/touchscreen/gt9xx/GT9110P_Config_20160217_1526_2048_97.cfg @@ -0,0 +1 @@ +0x00,0x00,0x06,0x00,0x08,0x0A,0x35,0x00,0x01,0xC8,0x28,0x08,0x5A,0x3C,0x03,0x05,0x00,0x00,0xFF,0x7F,0x00,0x00,0x04,0x18,0x1A,0x1E,0x14,0x8F,0x2F,0xAA,0x2A,0x2C,0x1E,0x14,0x00,0x00,0x00,0x21,0x33,0x2D,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x29,0x19,0x32,0x94,0xC5,0x02,0x08,0x00,0x00,0x04,0x99,0x1A,0x00,0x90,0x1E,0x00,0x87,0x23,0x00,0x81,0x28,0x00,0x7D,0x2E,0x00,0x7D,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x0F,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x19,0x46,0x32,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x13,0x12,0x11,0x10,0x0F,0x0E,0x0D,0x0C,0x0B,0x0A,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x26,0x25,0x24,0x23,0x22,0x21,0x20,0x1F,0x1E,0x1D,0x19,0x18,0x17,0x16,0x15,0x12,0x11,0x10,0x0F,0x0E,0x09,0x08,0x07,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x10,0x01 \ No newline at end of file diff --git a/drivers/amlogic/input/touchscreen/gt9xx/GT9271_Config_20170526.cfg b/drivers/amlogic/input/touchscreen/gt9xx/GT9271_Config_20170526.cfg new file mode 100644 index 0000000000000..a7ac38fe331e8 --- /dev/null +++ b/drivers/amlogic/input/touchscreen/gt9xx/GT9271_Config_20170526.cfg @@ -0,0 +1 @@ +0x00,0x80,0x07,0xB0,0x04,0x0A,0x3C,0x00,0x01,0x0A,0x28,0x1F,0x55,0x32,0x03,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x1A,0x1E,0x14,0x90,0x2F,0xAA,0x1E,0x20,0x31,0x0D,0x00,0x00,0x00,0x22,0x03,0x1D,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x2D,0x94,0xD5,0x02,0x08,0x00,0x00,0x04,0x9A,0x15,0x00,0x8C,0x19,0x00,0x80,0x1E,0x00,0x77,0x23,0x00,0x70,0x29,0x00,0x70,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,0x01,0x04,0x05,0x06,0x07,0x08,0x09,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x14,0x15,0x16,0x17,0x18,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x29,0x28,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20,0x1F,0x1E,0x1C,0x1B,0x19,0x14,0x13,0x12,0x11,0x10,0x0F,0x0E,0x0D,0x0C,0x0A,0x08,0x07,0x06,0x04,0x02,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x01 \ No newline at end of file diff --git a/drivers/amlogic/input/touchscreen/gt9xx/HLS-0102-1398V1-1060-GT911_Config_20201204_V66.cfg b/drivers/amlogic/input/touchscreen/gt9xx/HLS-0102-1398V1-1060-GT911_Config_20201204_V66.cfg new file mode 100644 index 0000000000000..77b72c416beaf --- /dev/null +++ b/drivers/amlogic/input/touchscreen/gt9xx/HLS-0102-1398V1-1060-GT911_Config_20201204_V66.cfg @@ -0,0 +1 @@ +0x42,0x00,0x03,0x00,0x04,0x0A,0x45,0x03,0x22,0x1F,0x28,0x0F,0x64,0x3C,0x03,0x0F,0x00,0x00,0x00,0x00,0x11,0x00,0x08,0x00,0x00,0x00,0x00,0x8B,0x29,0x0E,0x71,0x6F,0xB2,0x04,0x00,0x00,0x00,0x39,0x02,0x10,0x00,0x21,0x00,0x00,0x00,0x03,0x64,0x32,0x00,0x00,0x00,0x3C,0x78,0x94,0xD5,0x02,0x07,0x00,0x00,0x04,0xC8,0x40,0x00,0xB1,0x4A,0x00,0x9E,0x55,0x00,0x8E,0x61,0x00,0x7F,0x70,0x00,0x7F,0x70,0x00,0x00,0x00,0xF0,0x90,0x3C,0xFF,0xFF,0x07,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,0x1C,0x1A,0x18,0x16,0x14,0x12,0x10,0x0E,0x0C,0x0A,0x08,0x06,0x04,0x02,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x02,0x04,0x06,0x08,0x0A,0x0C,0x0F,0x10,0x12,0x13,0x16,0x18,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF6,0x01 \ No newline at end of file diff --git a/drivers/amlogic/input/touchscreen/gt9xx/Makefile b/drivers/amlogic/input/touchscreen/gt9xx/Makefile new file mode 100644 index 0000000000000..ce3ec6a34b4da --- /dev/null +++ b/drivers/amlogic/input/touchscreen/gt9xx/Makefile @@ -0,0 +1,6 @@ +# +# Makefile for the goodix gt9xx touchscreen drivers. +# +obj-$(CONFIG_TOUCHSCREEN_GT9XX) += gt9xx.o +obj-$(CONFIG_TOUCHSCREEN_GT9XX) += gt9xx_update.o +obj-$(CONFIG_TOUCHSCREEN_GT9XX) += goodix_tool.o diff --git a/drivers/amlogic/input/touchscreen/gt9xx/WGJ10162B_GT9271_1060_Config_20140821_1341110X42.cfg b/drivers/amlogic/input/touchscreen/gt9xx/WGJ10162B_GT9271_1060_Config_20140821_1341110X42.cfg new file mode 100644 index 0000000000000..db5ed0f34b828 --- /dev/null +++ b/drivers/amlogic/input/touchscreen/gt9xx/WGJ10162B_GT9271_1060_Config_20140821_1341110X42.cfg @@ -0,0 +1 @@ +0x42,0x80,0x07,0xB0,0x04,0x0A,0x35,0x00,0x02,0x0F,0x28,0x0F,0x5A,0x3C,0x03,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x17,0x19,0x1D,0x14,0x8F,0x2F,0xAA,0x37,0x39,0xD9,0x0B,0x00,0x00,0x00,0x83,0x02,0x1D,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2A,0x46,0x94,0xC5,0x02,0x07,0x00,0x00,0x04,0x95,0x2C,0x00,0x8A,0x31,0x00,0x81,0x36,0x00,0x79,0x3C,0x00,0x72,0x42,0x00,0x72,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,0x19,0x18,0x17,0x16,0x15,0x14,0x11,0x10,0x0F,0x0E,0x0D,0x0C,0x09,0x08,0x07,0x06,0x05,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x04,0x06,0x07,0x08,0x0A,0x0C,0x0D,0x0F,0x10,0x11,0x12,0x13,0x14,0x19,0x1B,0x1C,0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x16,0x01 \ No newline at end of file diff --git a/drivers/amlogic/input/touchscreen/gt9xx/WGJ10162B_GT9271_1920_1200.cfg b/drivers/amlogic/input/touchscreen/gt9xx/WGJ10162B_GT9271_1920_1200.cfg new file mode 100644 index 0000000000000..4071fdb99cd50 --- /dev/null +++ b/drivers/amlogic/input/touchscreen/gt9xx/WGJ10162B_GT9271_1920_1200.cfg @@ -0,0 +1 @@ +0x00,0x80,0x07,0xB0,0x04,0x0A,0x0D,0x00,0x01,0x08,0x28,0x05,0x50,0x32,0x03,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x30,0xAA,0x17,0x15,0x31,0x0D,0x00,0x00,0x01,0x99,0x04,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,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,0x01,0x04,0x05,0x06,0x07,0x08,0x09,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x14,0x15,0x16,0x17,0x18,0x19,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x02,0x04,0x06,0x07,0x08,0x0A,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,0x13,0x14,0x19,0x1B,0x1C,0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x4D,0x01 \ No newline at end of file diff --git a/drivers/amlogic/input/touchscreen/gt9xx/WGJ10162_GT9271_Config_20140820_182456.cfg b/drivers/amlogic/input/touchscreen/gt9xx/WGJ10162_GT9271_Config_20140820_182456.cfg new file mode 100644 index 0000000000000..96bf8cb7961ce --- /dev/null +++ b/drivers/amlogic/input/touchscreen/gt9xx/WGJ10162_GT9271_Config_20140820_182456.cfg @@ -0,0 +1 @@ +0x41,0x80,0x07,0xB0,0x04,0x0A,0x31,0x00,0x01,0x08,0x28,0x0F,0x50,0x32,0x03,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x8F,0x2F,0xAA,0x37,0x39,0xD3,0x07,0x00,0x00,0x00,0x02,0x02,0x1D,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x23,0x4B,0x94,0x45,0x02,0x07,0x00,0x00,0x00,0xB5,0x25,0x00,0x9B,0x2C,0x00,0x88,0x33,0x00,0x78,0x3B,0x00,0x6A,0x45,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,0x19,0x18,0x17,0x16,0x15,0x14,0x11,0x10,0x0F,0x0E,0x0D,0x0C,0x09,0x08,0x07,0x06,0x05,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x04,0x06,0x07,0x08,0x0A,0x0C,0x0D,0x0F,0x10,0x11,0x12,0x13,0x14,0x19,0x1B,0x1C,0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x8F,0x01 \ No newline at end of file diff --git a/drivers/amlogic/input/touchscreen/gt9xx/WGJ10187_GT910_Config_20140623_104014_0X41.cfg b/drivers/amlogic/input/touchscreen/gt9xx/WGJ10187_GT910_Config_20140623_104014_0X41.cfg new file mode 100644 index 0000000000000..ffc4679bf2d9e --- /dev/null +++ b/drivers/amlogic/input/touchscreen/gt9xx/WGJ10187_GT910_Config_20140623_104014_0X41.cfg @@ -0,0 +1 @@ +0x00, 0x00, 0x04, 0x58, 0x02, 0x05, 0x34, 0x20, 0x01, 0x1F, 0x14, 0x0F, 0x5A, 0x46, 0x03, 0x05, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x17, 0x19, 0x1B, 0x14, 0x89, 0x08, 0x0A, 0x3A, 0x00, 0x0F, 0x0A, 0x00, 0x00, 0x00, 0x1B, 0x02, 0x25, 0x3C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x4E, 0x94, 0xC5, 0x02, 0x08, 0x00, 0x00, 0x04, 0x92, 0x2C, 0x00, 0x88, 0x32, 0x00, 0x80, 0x39, 0x00, 0x7B, 0x40, 0x00, 0x76, 0x49, 0x00, 0x76, 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, 0x08, 0x0A, 0x0C, 0x0E, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x28, 0x24, 0x22, 0x20, 0x1F, 0x1E, 0x1D, 0x0E, 0x0C, 0x0A, 0x08, 0x06, 0x05, 0x04, 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, 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, 0x99, 0x01 \ No newline at end of file diff --git a/drivers/amlogic/input/touchscreen/gt9xx/WGJ10187_GT9271_Config_20140623_104014_0X41.cfg b/drivers/amlogic/input/touchscreen/gt9xx/WGJ10187_GT9271_Config_20140623_104014_0X41.cfg new file mode 100644 index 0000000000000..ffbfe3d547da2 --- /dev/null +++ b/drivers/amlogic/input/touchscreen/gt9xx/WGJ10187_GT9271_Config_20140623_104014_0X41.cfg @@ -0,0 +1 @@ +0x41,0xB0,0x04,0x80,0x07,0x0A,0xF5,0x00,0x01,0x08,0x28,0x0F,0x64,0x32,0x03,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x16,0x19,0x1E,0x14,0x8F,0x2F,0x99,0x41,0x43,0x15,0x0E,0x00,0x00,0x00,0x22,0x03,0x1D,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x2D,0x62,0x94,0xC5,0x02,0x07,0x17,0x00,0x04,0x92,0x30,0x00,0x86,0x39,0x00,0x7F,0x42,0x00,0x79,0x4D,0x00,0x74,0x5A,0x00,0x74,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,0x17,0x16,0x15,0x14,0x11,0x10,0x0F,0x0E,0x0D,0x0C,0x09,0x08,0x07,0x06,0x05,0x04,0x01,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x04,0x06,0x07,0x08,0x0A,0x0C,0x0D,0x0F,0x10,0x11,0x12,0x13,0x14,0x29,0x28,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20,0x1F,0x1E,0x1C,0x1B,0x19,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x01 \ No newline at end of file diff --git a/drivers/amlogic/input/touchscreen/gt9xx/WGJ89006B_GT911_Config_20140625_085816_0X43.cfg b/drivers/amlogic/input/touchscreen/gt9xx/WGJ89006B_GT911_Config_20140625_085816_0X43.cfg new file mode 100644 index 0000000000000..1c42d9ef7ce13 --- /dev/null +++ b/drivers/amlogic/input/touchscreen/gt9xx/WGJ89006B_GT911_Config_20140625_085816_0X43.cfg @@ -0,0 +1 @@ +0x43,0x00,0x10,0x00,0x10,0x0A,0x3D,0x20,0x01,0x08,0x28,0x08,0x50,0x32,0x03,0x05,0x00,0x00,0x00,0x00,0x11,0x00,0x00,0x18,0x1A,0x20,0x14,0x8C,0x2E,0x0E,0x3C,0x3E,0x0C,0x08,0x00,0x00,0x00,0x41,0x03,0x1D,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x5A,0x94,0xC5,0x02,0x08,0x00,0x00,0x04,0xA0,0x36,0x00,0x8B,0x3C,0x00,0x7C,0x43,0x00,0x6B,0x4C,0x00,0x5F,0x55,0x00,0x5F,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,0x02,0x04,0x06,0x08,0x0A,0x0C,0x0E,0x10,0x12,0x14,0x16,0x18,0x1A,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x04,0x06,0x08,0x0A,0x0C,0x0F,0x10,0x12,0x13,0x14,0x16,0x18,0x1C,0x1D,0x1E,0x1F,0x2A,0x29,0x28,0x26,0x24,0x22,0x21,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x01 \ No newline at end of file diff --git a/drivers/amlogic/input/touchscreen/gt9xx/WGJ89006B_GT9271_Config_20140625_085816_0X41.cfg b/drivers/amlogic/input/touchscreen/gt9xx/WGJ89006B_GT9271_Config_20140625_085816_0X41.cfg new file mode 100644 index 0000000000000..7ed0266acfaa0 --- /dev/null +++ b/drivers/amlogic/input/touchscreen/gt9xx/WGJ89006B_GT9271_Config_20140625_085816_0X41.cfg @@ -0,0 +1 @@ +0x41,0x80,0x07,0xB0,0x04,0x0A,0x05,0x00,0x01,0x08,0x28,0x0F,0x50,0x32,0x03,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x8F,0x2F,0x99,0x2B,0x2D,0x31,0x0D,0x00,0x00,0x00,0x01,0x03,0x1D,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x23,0x55,0x94,0xC5,0x02,0x07,0x00,0x00,0x00,0x8C,0x26,0x00,0x7B,0x2D,0x00,0x6C,0x36,0x00,0x61,0x41,0x00,0x58,0x4E,0x00,0x58,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,0x01,0x04,0x05,0x06,0x07,0x08,0x09,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x14,0x15,0x16,0x17,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x13,0x12,0x11,0x10,0x0F,0x0D,0x0C,0x0A,0x08,0x07,0x06,0x04,0x02,0x00,0x19,0x1B,0x1C,0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xB5,0x01 \ No newline at end of file diff --git a/drivers/amlogic/input/touchscreen/gt9xx/goodix_tool.c b/drivers/amlogic/input/touchscreen/gt9xx/goodix_tool.c new file mode 100644 index 0000000000000..49e23f9c630c6 --- /dev/null +++ b/drivers/amlogic/input/touchscreen/gt9xx/goodix_tool.c @@ -0,0 +1,619 @@ +/* + * Goodix GT9xx touchscreen driver + * + * Copyright (C) 2010 - 2016 Goodix. Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be a reference + * to you, when you are integrating the GOODiX's CTP IC into your system, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * Version: 2.4.0.1 + * Release Date: 2016/10/26 + */ + + +#include "gt9xx.h" + +#define DATA_LENGTH_UINT 512 +#define CMD_HEAD_LENGTH (sizeof(st_cmd_head) - sizeof(u8*)) +static char procname[20] = {0}; + +#define UPDATE_FUNCTIONS + +#ifdef UPDATE_FUNCTIONS +extern s32 gup_enter_update_mode(struct i2c_client *client); +extern void gup_leave_update_mode(void); +extern s32 gup_update_proc(void *dir); +#endif + +extern void gtp_irq_disable(struct goodix_ts_data *); +extern void gtp_irq_enable(struct goodix_ts_data *); + +#pragma pack(1) +typedef struct{ + u8 wr; //write read flag٬0:R 1:W 2:PID 3: + u8 flag; //0:no need flag/int 1: need flag 2:need int + u8 flag_addr[2]; //flag address + u8 flag_val; //flag val + u8 flag_relation; //flag_val:flag 0:not equal 1:equal 2:> 3:< + u16 circle; //polling cycle + u8 times; //plling times + u8 retry; //I2C retry times + u16 delay; //delay befor read or after write + u16 data_len; //data length + u8 addr_len; //address length + u8 addr[2]; //address + u8 res[3]; //reserved + u8* data; //data pointer +}st_cmd_head; +#pragma pack() +static st_cmd_head cmd_head; + +static struct i2c_client *gt_client = NULL; + +static struct proc_dir_entry *goodix_proc_entry; + +static ssize_t goodix_tool_read(struct file *, char __user *, size_t, loff_t *); +static ssize_t goodix_tool_write(struct file *, const char __user *, size_t, loff_t *); +static const struct file_operations tool_ops = { + .owner = THIS_MODULE, + .read = goodix_tool_read, + .write = goodix_tool_write, +}; + +//static s32 goodix_tool_write(struct file *filp, const char __user *buff, unsigned long len, void *data); +//static s32 goodix_tool_read( char *page, char **start, off_t off, int count, int *eof, void *data ); +static s32 (*tool_i2c_read)(u8 *, u16); +static s32 (*tool_i2c_write)(u8 *, u16); + +#if GTP_ESD_PROTECT +extern void gtp_esd_switch(struct i2c_client *, s32); +#endif +static s32 DATA_LENGTH; +static s8 IC_TYPE[16] = "GT9XX"; + +static void tool_set_proc_name(char * procname) +{ + char *months[12] = {"Jan", "Feb", "Mar", "Apr", "May", + "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; + char date[20] = {0}; + char month[4] = {0}; + int i = 0, n_month = 1, n_day = 0, n_year = 0; + + //GTP_DEBUG("compile date: %s", date); + + sscanf(date, "%s %d %d", month, &n_day, &n_year); + + for (i = 0; i < 12; ++i) + { + if (!memcmp(months[i], month, 3)) + { + n_month = i+1; + break; + } + } + + sprintf(procname, "gmnode%04d%02d%02d", n_year, n_month, n_day); + //sprintf(procname, "goodix_tool"); + //GTP_DEBUG("procname = %s", procname); +} + + +static s32 tool_i2c_read_no_extra(u8* buf, u16 len) +{ + s32 ret = -1; + s32 i = 0; + struct i2c_msg msgs[2]; + + msgs[0].flags = !I2C_M_RD; + msgs[0].addr = gt_client->addr; + msgs[0].len = cmd_head.addr_len; + msgs[0].buf = &buf[0]; + + msgs[1].flags = I2C_M_RD; + msgs[1].addr = gt_client->addr; + msgs[1].len = len; + msgs[1].buf = &buf[GTP_ADDR_LENGTH]; + + for (i = 0; i < cmd_head.retry; i++) + { + ret=i2c_transfer(gt_client->adapter, msgs, 2); + if (ret > 0) + { + break; + } + } + return ret; +} + +static s32 tool_i2c_write_no_extra(u8* buf, u16 len) +{ + s32 ret = -1; + s32 i = 0; + struct i2c_msg msg; + + msg.flags = !I2C_M_RD; + msg.addr = gt_client->addr; + msg.len = len; + msg.buf = buf; + + for (i = 0; i < cmd_head.retry; i++) + { + ret=i2c_transfer(gt_client->adapter, &msg, 1); + if (ret > 0) + { + break; + } + } + return ret; +} + +static s32 tool_i2c_read_with_extra(u8* buf, u16 len) +{ + s32 ret = -1; + u8 pre[2] = {0x0f, 0xff}; + u8 end[2] = {0x80, 0x00}; + + tool_i2c_write_no_extra(pre, 2); + ret = tool_i2c_read_no_extra(buf, len); + tool_i2c_write_no_extra(end, 2); + + return ret; +} + +static s32 tool_i2c_write_with_extra(u8* buf, u16 len) +{ + s32 ret = -1; + u8 pre[2] = {0x0f, 0xff}; + u8 end[2] = {0x80, 0x00}; + + tool_i2c_write_no_extra(pre, 2); + ret = tool_i2c_write_no_extra(buf, len); + tool_i2c_write_no_extra(end, 2); + + return ret; +} + +static void register_i2c_func(void) +{ +// if (!strncmp(IC_TYPE, "GT818", 5) || !strncmp(IC_TYPE, "GT816", 5) +// || !strncmp(IC_TYPE, "GT811", 5) || !strncmp(IC_TYPE, "GT818F", 6) +// || !strncmp(IC_TYPE, "GT827", 5) || !strncmp(IC_TYPE,"GT828", 5) +// || !strncmp(IC_TYPE, "GT813", 5)) + if (strncmp(IC_TYPE, "GT8110", 6) && strncmp(IC_TYPE, "GT8105", 6) + && strncmp(IC_TYPE, "GT801", 5) && strncmp(IC_TYPE, "GT800", 5) + && strncmp(IC_TYPE, "GT801PLUS", 9) && strncmp(IC_TYPE, "GT811", 5) + && strncmp(IC_TYPE, "GTxxx", 5) && strncmp(IC_TYPE, "GT9XX", 5)) + { + tool_i2c_read = tool_i2c_read_with_extra; + tool_i2c_write = tool_i2c_write_with_extra; + GTP_DEBUG("I2C function: with pre and end cmd!"); + } + else + { + tool_i2c_read = tool_i2c_read_no_extra; + tool_i2c_write = tool_i2c_write_no_extra; + GTP_INFO("I2C function: without pre and end cmd!"); + } +} + +static void unregister_i2c_func(void) +{ + tool_i2c_read = NULL; + tool_i2c_write = NULL; + GTP_INFO("I2C function: unregister i2c transfer function!"); +} + +s32 init_wr_node(struct i2c_client *client) +{ + s32 i; + + DATA_LENGTH = 0; + gt_client = client; + memset(&cmd_head, 0, sizeof(cmd_head)); + cmd_head.data = NULL; + + i = 5; + while ((!cmd_head.data) && i) + { + cmd_head.data = kzalloc(i * DATA_LENGTH_UINT, GFP_KERNEL); + if (NULL != cmd_head.data) + { + break; + } + i--; + } + if (i) + { + DATA_LENGTH = i * DATA_LENGTH_UINT + GTP_ADDR_LENGTH; + GTP_INFO("Applied memory size:%d.", DATA_LENGTH); + } + else + { + GTP_ERROR("Apply for memory failed."); + return FAIL; + } + + cmd_head.addr_len = 2; + cmd_head.retry = 5; + + register_i2c_func(); + + tool_set_proc_name(procname); + goodix_proc_entry = proc_create(procname, 0666, NULL, &tool_ops); + if (goodix_proc_entry == NULL) + { + GTP_ERROR("Couldn't create proc entry!"); + return FAIL; + } + else + { + GTP_INFO("Create proc entry success!"); + } + + return SUCCESS; +} + +void uninit_wr_node(void) +{ + kfree(cmd_head.data); + cmd_head.data = NULL; + unregister_i2c_func(); + remove_proc_entry(procname, NULL); +} + +static u8 relation(u8 src, u8 dst, u8 rlt) +{ + u8 ret = 0; + + switch (rlt) + { + case 0: + ret = (src != dst) ? true : false; + break; + + case 1: + ret = (src == dst) ? true : false; + GTP_DEBUG("equal:src:0x%02x dst:0x%02x ret:%d.", src, dst, (s32)ret); + break; + + case 2: + ret = (src > dst) ? true : false; + break; + + case 3: + ret = (src < dst) ? true : false; + break; + + case 4: + ret = (src & dst) ? true : false; + break; + + case 5: + ret = (!(src | dst)) ? true : false; + break; + + default: + ret = false; + break; + } + + return ret; +} + +/******************************************************* +Function: + Comfirm function. +Input: + None. +Output: + Return write length. +********************************************************/ +static u8 comfirm(void) +{ + s32 i = 0; + u8 buf[32]; + + memcpy(buf, cmd_head.flag_addr, cmd_head.addr_len); + + for (i = 0; i < cmd_head.times; i++) + { + if (tool_i2c_read(buf, 1) <= 0) + { + GTP_ERROR("Read flag data failed!"); + return FAIL; + } + if (true == relation(buf[GTP_ADDR_LENGTH], cmd_head.flag_val, cmd_head.flag_relation)) + { + GTP_DEBUG("value at flag addr:0x%02x.", buf[GTP_ADDR_LENGTH]); + GTP_DEBUG("flag value:0x%02x.", cmd_head.flag_val); + break; + } + + msleep(cmd_head.circle); + } + + if (i >= cmd_head.times) + { + GTP_ERROR("Didn't get the flag to continue!"); + return FAIL; + } + + return SUCCESS; +} + +/******************************************************* +Function: + Goodix tool write function. +Input: + standard proc write function param. +Output: + Return write length. +********************************************************/ +//static s32 goodix_tool_write(struct file *filp, const char __user *buff, unsigned long len, void *data) +ssize_t goodix_tool_write(struct file *filp, const char __user *buff, size_t len, loff_t *off) +{ + s32 ret = 0; + + GTP_DEBUG_FUNC(); + GTP_DEBUG_ARRAY((u8*)buff, len); + + ret = copy_from_user(&cmd_head, buff, CMD_HEAD_LENGTH); + if(ret) + { + GTP_ERROR("copy_from_user failed."); + return -EPERM; + } + + + GTP_DEBUG("[Operation]wr: %02X", cmd_head.wr); + GTP_DEBUG("[Flag]flag: %02X, addr: %02X%02X, value: %02X, relation: %02X", cmd_head.flag, cmd_head.flag_addr[0], + cmd_head.flag_addr[1], cmd_head.flag_val, cmd_head.flag_relation); + GTP_DEBUG("[Retry]circle: %d, times: %d, retry: %d, delay: %d", (s32)cmd_head.circle, (s32)cmd_head.times, + (s32)cmd_head.retry, (s32)cmd_head.delay); + GTP_DEBUG("[Data]data len: %d, addr len: %d, addr: %02X%02X, buffer len: %d, data[0]: %02X", (s32)cmd_head.data_len, + (s32)cmd_head.addr_len, cmd_head.addr[0], cmd_head.addr[1], (s32)len, buff[CMD_HEAD_LENGTH]); + + if (1 == cmd_head.wr) + { + ret = copy_from_user(&cmd_head.data[GTP_ADDR_LENGTH], &buff[CMD_HEAD_LENGTH], cmd_head.data_len); + if(ret) + { + GTP_ERROR("copy_from_user failed."); + return -EPERM; + } + memcpy(&cmd_head.data[GTP_ADDR_LENGTH - cmd_head.addr_len], cmd_head.addr, cmd_head.addr_len); + + GTP_DEBUG_ARRAY(cmd_head.data, cmd_head.data_len + cmd_head.addr_len); + GTP_DEBUG_ARRAY((u8*)&buff[CMD_HEAD_LENGTH], cmd_head.data_len); + + if (1 == cmd_head.flag) + { + if (FAIL == comfirm()) + { + GTP_ERROR("[WRITE]Comfirm fail!"); + return -EPERM; + } + } + else if (2 == cmd_head.flag) + { + //Need interrupt! + } + if (tool_i2c_write(&cmd_head.data[GTP_ADDR_LENGTH - cmd_head.addr_len], + cmd_head.data_len + cmd_head.addr_len) <= 0) + { + GTP_ERROR("[WRITE]Write data failed!"); + return -EPERM; + } + + GTP_DEBUG_ARRAY(&cmd_head.data[GTP_ADDR_LENGTH - cmd_head.addr_len],cmd_head.data_len + cmd_head.addr_len); + if (cmd_head.delay) + { + msleep(cmd_head.delay); + } + } + else if (3 == cmd_head.wr) //Write ic type + { + ret = copy_from_user(&cmd_head.data[0], &buff[CMD_HEAD_LENGTH], cmd_head.data_len); + if(ret) + { + GTP_ERROR("copy_from_user failed."); + return -EPERM; + } + memcpy(IC_TYPE, cmd_head.data, cmd_head.data_len); + + register_i2c_func(); + } + else if (5 == cmd_head.wr) + { + //memcpy(IC_TYPE, cmd_head.data, cmd_head.data_len); + } + else if (7 == cmd_head.wr)//disable irq! + { + gtp_irq_disable(i2c_get_clientdata(gt_client)); + + #if GTP_ESD_PROTECT + gtp_esd_switch(gt_client, SWITCH_OFF); + #endif + } + else if (9 == cmd_head.wr) //enable irq! + { + gtp_irq_enable(i2c_get_clientdata(gt_client)); + + #if GTP_ESD_PROTECT + gtp_esd_switch(gt_client, SWITCH_ON); + #endif + } + else if(17 == cmd_head.wr) + { + struct goodix_ts_data *ts = i2c_get_clientdata(gt_client); + ret = copy_from_user(&cmd_head.data[GTP_ADDR_LENGTH], &buff[CMD_HEAD_LENGTH], cmd_head.data_len); + if(ret) + { + GTP_DEBUG("copy_from_user failed."); + return -EPERM; + } + if(cmd_head.data[GTP_ADDR_LENGTH]) + { + GTP_INFO("gtp enter rawdiff."); + ts->gtp_rawdiff_mode = true; + } + else + { + ts->gtp_rawdiff_mode = false; + GTP_INFO("gtp leave rawdiff."); + } + } +#ifdef UPDATE_FUNCTIONS + else if (11 == cmd_head.wr)//Enter update mode! + { + if (FAIL == gup_enter_update_mode(gt_client)) + { + return -EPERM; + } + } + else if (13 == cmd_head.wr)//Leave update mode! + { + gup_leave_update_mode(); + } + else if (15 == cmd_head.wr) //Update firmware! + { + show_len = 0; + total_len = 0; + memset(cmd_head.data, 0, (int)(cmd_head.data_len + 1)); + memcpy(cmd_head.data, &buff[CMD_HEAD_LENGTH], cmd_head.data_len); + + if (FAIL == gup_update_proc((void*)cmd_head.data)) + { + return -EPERM; + } + } + +#endif + + return len; +} + +/******************************************************* +Function: + Goodix tool read function. +Input: + standard proc read function param. +Output: + Return read length. +********************************************************/ +ssize_t goodix_tool_read(struct file *file, char __user *page, size_t size, loff_t *ppos) +{ + s32 ret = 0; + + GTP_DEBUG_FUNC(); + + if (*ppos) // ADB call again + { + //GTP_DEBUG("[HEAD]wr: %d", cmd_head.wr); + //GTP_DEBUG("[PARAM]size: %d, *ppos: %d", size, (int)*ppos); + //GTP_DEBUG("[TOOL_READ]ADB call again, return it."); + *ppos = 0; + return 0; + } + + if (cmd_head.wr % 2) + { + return -EPERM; + } + else if (!cmd_head.wr) + { + u16 len = 0; + s16 data_len = 0; + u16 loc = 0; + + if (1 == cmd_head.flag) + { + if (FAIL == comfirm()) + { + GTP_ERROR("[READ]Comfirm fail!"); + return -EPERM; + } + } + else if (2 == cmd_head.flag) + { + //Need interrupt! + } + + memcpy(cmd_head.data, cmd_head.addr, cmd_head.addr_len); + + GTP_DEBUG("[CMD HEAD DATA] ADDR:0x%02x%02x.", cmd_head.data[0], cmd_head.data[1]); + GTP_DEBUG("[CMD HEAD ADDR] ADDR:0x%02x%02x.", cmd_head.addr[0], cmd_head.addr[1]); + + if (cmd_head.delay) + { + msleep(cmd_head.delay); + } + + data_len = cmd_head.data_len; + + while(data_len > 0) + { + if (data_len > DATA_LENGTH) + { + len = DATA_LENGTH; + } + else + { + len = data_len; + } + data_len -= len; + + if (tool_i2c_read(cmd_head.data, len) <= 0) + { + GTP_ERROR("[READ]Read data failed!"); + return -EPERM; + } + + //memcpy(&page[loc], &cmd_head.data[GTP_ADDR_LENGTH], len); + ret = simple_read_from_buffer(&page[loc], size, ppos, &cmd_head.data[GTP_ADDR_LENGTH], len); + if (ret < 0) + { + return ret; + } + loc += len; + + GTP_DEBUG_ARRAY(&cmd_head.data[GTP_ADDR_LENGTH], len); + GTP_DEBUG_ARRAY(page, len); + } + return cmd_head.data_len; + } + else if (2 == cmd_head.wr) + { + ret = simple_read_from_buffer(page, size, ppos, IC_TYPE, sizeof(IC_TYPE)); + return ret; + } + else if (4 == cmd_head.wr) + { + u8 progress_buf[4]; + progress_buf[0] = show_len >> 8; + progress_buf[1] = show_len & 0xff; + progress_buf[2] = total_len >> 8; + progress_buf[3] = total_len & 0xff; + + ret = simple_read_from_buffer(page, size, ppos, progress_buf, 4); + return ret; + } + else if (6 == cmd_head.wr) + { + //Read error code! + } + else if (8 == cmd_head.wr) //Read driver version + { + ret = simple_read_from_buffer(page, size, ppos, GTP_DRIVER_VERSION, strlen(GTP_DRIVER_VERSION)); + return ret; + } + return -EPERM; +} diff --git a/drivers/amlogic/input/touchscreen/gt9xx/gt9xx.c b/drivers/amlogic/input/touchscreen/gt9xx/gt9xx.c new file mode 100644 index 0000000000000..18c9bef0c1707 --- /dev/null +++ b/drivers/amlogic/input/touchscreen/gt9xx/gt9xx.c @@ -0,0 +1,3165 @@ +/* + * Goodix GT9xx touchscreen driver + * + * Copyright (C) 2010 - 2016 Goodix. Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be a reference + * to you, when you are integrating the GOODiX's CTP IC into your system, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * Version: 2.4.0.1 + * Release Date: 2016/10/26 + */ + +#include +#include "gt9xx.h" + +#if GTP_ICS_SLOT_REPORT + #include +#endif + +static const char *goodix_ts_name = "goodix-ts"; +static const char *goodix_input_phys = "input/ts"; +static struct workqueue_struct *goodix_wq; +struct i2c_client * i2c_connect_client = NULL; +int gtp_rst_gpio; +int gtp_int_gpio; +static u32 rotation; +u8 config[GTP_CONFIG_MAX_LENGTH + GTP_ADDR_LENGTH] + = {GTP_REG_CONFIG_DATA >> 8, GTP_REG_CONFIG_DATA & 0xff}; + +#if GTP_HAVE_TOUCH_KEY + static const u16 touch_key_array[] = GTP_KEY_TAB; + #define GTP_MAX_KEY_NUM (sizeof(touch_key_array)/sizeof(touch_key_array[0])) + +#if GTP_DEBUG_ON + static const int key_codes[] = {KEY_HOME, KEY_BACK, KEY_MENU, KEY_HOMEPAGE, KEY_F1, KEY_F2, KEY_F3}; + static const char *key_names[] = {"Key_Home", "Key_Back", "Key_Menu", "Key_Homepage", "KEY_F1", "KEY_F2", "KEY_F3"}; +#endif + +#endif + +static s8 gtp_i2c_test(struct i2c_client *client); +void gtp_reset_guitar(struct i2c_client *client, s32 ms); +s32 gtp_send_cfg(struct i2c_client *client); +void gtp_int_sync(s32 ms); + +static ssize_t gt91xx_config_read_proc(struct file *, char __user *, size_t, loff_t *); +static ssize_t gt91xx_config_write_proc(struct file *, const char __user *, size_t, loff_t *); + +static struct proc_dir_entry *gt91xx_config_proc = NULL; +static const struct file_operations config_proc_ops = { + .owner = THIS_MODULE, + .read = gt91xx_config_read_proc, + .write = gt91xx_config_write_proc, +}; +static int gtp_register_powermanger(struct goodix_ts_data *ts); +static int gtp_unregister_powermanger(struct goodix_ts_data *ts); + +#if GTP_CREATE_WR_NODE +extern s32 init_wr_node(struct i2c_client*); +extern void uninit_wr_node(void); +#endif + +#if GTP_AUTO_UPDATE +extern u8 gup_init_update_proc(struct goodix_ts_data *); +#endif + +#if GTP_ESD_PROTECT +static struct delayed_work gtp_esd_check_work; +static struct workqueue_struct * gtp_esd_check_workqueue = NULL; +static void gtp_esd_check_func(struct work_struct *); +static s32 gtp_init_ext_watchdog(struct i2c_client *client); +void gtp_esd_switch(struct i2c_client *, s32); +#endif + +//*********** For GT9XXF Start **********// +#if GTP_COMPATIBLE_MODE +extern s32 i2c_read_bytes(struct i2c_client *client, u16 addr, u8 *buf, s32 len); +extern s32 i2c_write_bytes(struct i2c_client *client, u16 addr, u8 *buf, s32 len); +extern s32 gup_clk_calibration(void); +extern s32 gup_fw_download_proc(void *dir, u8 dwn_mode); +extern u8 gup_check_fs_mounted(char *path_name); + +void gtp_recovery_reset(struct i2c_client *client); +static s32 gtp_esd_recovery(struct i2c_client *client); +s32 gtp_fw_startup(struct i2c_client *client); +static s32 gtp_main_clk_proc(struct goodix_ts_data *ts); +static s32 gtp_bak_ref_proc(struct goodix_ts_data *ts, u8 mode); + +#endif +//********** For GT9XXF End **********// + +#if GTP_GESTURE_WAKEUP +typedef enum +{ + DOZE_DISABLED = 0, + DOZE_ENABLED = 1, + DOZE_WAKEUP = 2, +}DOZE_T; +static DOZE_T doze_status = DOZE_DISABLED; +static s8 gtp_enter_doze(struct goodix_ts_data *ts); +#endif + +#ifdef GTP_CONFIG_OF +int gtp_parse_dt_cfg(struct device *dev, u8 *cfg, int *cfg_len, u8 sid); +#endif + +/******************************************************* +Function: + Read data from the i2c slave device. +Input: + client: i2c device. + buf[0~1]: read start address. + buf[2~len-1]: read data buffer. + len: GTP_ADDR_LENGTH + read bytes count +Output: + numbers of i2c_msgs to transfer: + 2: succeed, otherwise: failed +*********************************************************/ +s32 gtp_i2c_read(struct i2c_client *client, u8 *buf, s32 len) +{ + struct i2c_msg msgs[2]; + s32 ret=-1; + s32 retries = 0; + + GTP_DEBUG_FUNC(); + + msgs[0].flags = !I2C_M_RD; + msgs[0].addr = client->addr; + msgs[0].len = GTP_ADDR_LENGTH; + msgs[0].buf = &buf[0]; + //msgs[0].scl_rate = 300 * 1000; // for Rockchip, etc. + + msgs[1].flags = I2C_M_RD; + msgs[1].addr = client->addr; + msgs[1].len = len - GTP_ADDR_LENGTH; + msgs[1].buf = &buf[GTP_ADDR_LENGTH]; + //msgs[1].scl_rate = 300 * 1000; + + while(retries < 5) + { + ret = i2c_transfer(client->adapter, msgs, 2); + if(ret == 2)break; + retries++; + } + if((retries >= 5)) + { + #if GTP_COMPATIBLE_MODE + struct goodix_ts_data *ts = i2c_get_clientdata(client); + #endif + + #if GTP_GESTURE_WAKEUP + // reset chip would quit doze mode + if (DOZE_ENABLED == doze_status) + { + return ret; + } + #endif + GTP_ERROR("I2C Read: 0x%04X, %d bytes failed, errcode: %d! Process reset.", (((u16)(buf[0] << 8)) | buf[1]), len-2, ret); + #if GTP_COMPATIBLE_MODE + if (CHIP_TYPE_GT9F == ts->chip_type) + { + gtp_recovery_reset(client); + } + else + #endif + { + gtp_reset_guitar(client, 10); + } + } + return ret; +} + + + +/******************************************************* +Function: + Write data to the i2c slave device. +Input: + client: i2c device. + buf[0~1]: write start address. + buf[2~len-1]: data buffer + len: GTP_ADDR_LENGTH + write bytes count +Output: + numbers of i2c_msgs to transfer: + 1: succeed, otherwise: failed +*********************************************************/ +s32 gtp_i2c_write(struct i2c_client *client,u8 *buf,s32 len) +{ + struct i2c_msg msg; + s32 ret = -1; + s32 retries = 0; + + GTP_DEBUG_FUNC(); + + msg.flags = !I2C_M_RD; + msg.addr = client->addr; + msg.len = len; + msg.buf = buf; + //msg.scl_rate = 300 * 1000; // for Rockchip, etc + + while(retries < 5) + { + ret = i2c_transfer(client->adapter, &msg, 1); + if (ret == 1)break; + retries++; + } + if((retries >= 5)) + { + #if GTP_COMPATIBLE_MODE + struct goodix_ts_data *ts = i2c_get_clientdata(client); + #endif + + #if GTP_GESTURE_WAKEUP + if (DOZE_ENABLED == doze_status) + { + return ret; + } + #endif + GTP_ERROR("I2C Write: 0x%04X, %d bytes failed, errcode: %d! Process reset.", (((u16)(buf[0] << 8)) | buf[1]), len-2, ret); + #if GTP_COMPATIBLE_MODE + if (CHIP_TYPE_GT9F == ts->chip_type) + { + gtp_recovery_reset(client); + } + else + #endif + { + gtp_reset_guitar(client, 10); + } + } + return ret; +} + + +/******************************************************* +Function: + i2c read twice, compare the results +Input: + client: i2c device + addr: operate address + rxbuf: read data to store, if compare successful + len: bytes to read +Output: + FAIL: read failed + SUCCESS: read successful +*********************************************************/ +s32 gtp_i2c_read_dbl_check(struct i2c_client *client, u16 addr, u8 *rxbuf, int len) +{ + u8 buf[16] = {0}; + u8 confirm_buf[16] = {0}; + u8 retry = 0; + + while (retry++ < 3) + { + memset(buf, 0xAA, 16); + buf[0] = (u8)(addr >> 8); + buf[1] = (u8)(addr & 0xFF); + gtp_i2c_read(client, buf, len + 2); + + memset(confirm_buf, 0xAB, 16); + confirm_buf[0] = (u8)(addr >> 8); + confirm_buf[1] = (u8)(addr & 0xFF); + gtp_i2c_read(client, confirm_buf, len + 2); + + if (!memcmp(buf, confirm_buf, len+2)) + { + memcpy(rxbuf, confirm_buf+2, len); + return SUCCESS; + } + } + GTP_ERROR("I2C read 0x%04X, %d bytes, double check failed!", addr, len); + return FAIL; +} + +/******************************************************* +Function: + Send config. +Input: + client: i2c device. +Output: + result of i2c write operation. + 1: succeed, otherwise: failed +*********************************************************/ + +s32 gtp_send_cfg(struct i2c_client *client) +{ + s32 ret = 2; + +#if GTP_DRIVER_SEND_CFG + s32 retry = 0; + struct goodix_ts_data *ts = i2c_get_clientdata(client); + + if (ts->pnl_init_error) + { + GTP_INFO("Error occured in init_panel, no config sent"); + return 0; + } + + GTP_INFO("Driver send config."); + for (retry = 0; retry < 5; retry++) + { + ret = gtp_i2c_write(client, config , GTP_CONFIG_MAX_LENGTH + GTP_ADDR_LENGTH); + if (ret > 0) + { + break; + } + } +#endif + return ret; +} +/******************************************************* +Function: + Disable irq function +Input: + ts: goodix i2c_client private data +Output: + None. +*********************************************************/ +void gtp_irq_disable(struct goodix_ts_data *ts) +{ + unsigned long irqflags; + + GTP_DEBUG_FUNC(); + + spin_lock_irqsave(&ts->irq_lock, irqflags); + if (!ts->irq_is_disable) + { + ts->irq_is_disable = 1; + disable_irq_nosync(ts->client->irq); + } + spin_unlock_irqrestore(&ts->irq_lock, irqflags); +} + +/******************************************************* +Function: + Enable irq function +Input: + ts: goodix i2c_client private data +Output: + None. +*********************************************************/ +void gtp_irq_enable(struct goodix_ts_data *ts) +{ + unsigned long irqflags = 0; + + GTP_DEBUG_FUNC(); + + spin_lock_irqsave(&ts->irq_lock, irqflags); + if (ts->irq_is_disable) + { + enable_irq(ts->client->irq); + ts->irq_is_disable = 0; + } + spin_unlock_irqrestore(&ts->irq_lock, irqflags); +} + + +/******************************************************* +Function: + Report touch point event +Input: + ts: goodix i2c_client private data + id: trackId + x: input x coordinate + y: input y coordinate + w: input pressure +Output: + None. +*********************************************************/ +static void gtp_touch_down(struct goodix_ts_data* ts,s32 id,s32 x,s32 y,s32 w) +{ +#if GTP_CHANGE_X2Y + GTP_SWAP(x, y); +#endif + +#if GTP_X_REVERSE_ENABLE + x = ts->abs_x_max - x; +#endif + +#if GTP_Y_REVERSE_ENABLE + y = ts->abs_y_max - y; +#endif + +#if GTP_ICS_SLOT_REPORT + + + input_mt_slot(ts->input_dev, id); + input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, id); + if(id==9){ + input_mt_report_slot_state(ts->input_dev,MT_TOOL_PEN,true); + }else{ + input_mt_report_slot_state(ts->input_dev,MT_TOOL_FINGER,true); + } + input_report_abs(ts->input_dev, ABS_MT_PRESSURE, w); + + if (2 == rotation) { + input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x); + input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, ts->abs_y_max-y); + }else if (3 == rotation) { + input_report_abs(ts->input_dev, ABS_MT_POSITION_X, ts->abs_x_max-x); + input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, ts->abs_y_max-y); + }else{ + input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x); + input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y); + } + input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, w); + input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, w); +#else + + if((id & 0x80)) {//pen + id = 9; + input_report_abs(ts->input_dev, ABS_MT_TOOL_TYPE, 1); + } else {//finger + id = id & 0x0F; + input_report_abs(ts->input_dev, ABS_MT_TOOL_TYPE, 0 ); + } + input_report_key(ts->input_dev, BTN_TOUCH, 1); + input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, id); + input_report_abs(ts->input_dev, ABS_MT_PRESSURE, w); + input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, w); + input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, w); + input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x); + input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y); + + input_mt_sync(ts->input_dev); +#endif + + GTP_DEBUG("ID:%d, X:%d, Y:%d, W:%d", id, x, y, w); +} + +/******************************************************* +Function: + Report touch release event +Input: + ts: goodix i2c_client private data +Output: + None. +*********************************************************/ +static void gtp_touch_up(struct goodix_ts_data* ts, s32 id) +{ +#if GTP_ICS_SLOT_REPORT + input_mt_slot(ts->input_dev, id); + input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, -1); + GTP_DEBUG("Touch id[%2d] release!", id); +#else + input_report_key(ts->input_dev, BTN_TOUCH, 0); +input_mt_sync(ts->input_dev); + +#endif +} + +#if GTP_WITH_HOVER + +static void gtp_pen_init(struct goodix_ts_data *ts) +{ + s32 ret = 0; + + GTP_INFO("Request input device for pen/stylus."); + + ts->pen_dev = input_allocate_device(); + if (ts->pen_dev == NULL) + { + GTP_ERROR("Failed to allocate input device for pen/stylus."); + return; + } + + ts->pen_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) ; + ts->pen_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); + set_bit(BTN_TOOL_PEN, ts->pen_dev->keybit); + + input_set_abs_params(ts->pen_dev, ABS_MT_POSITION_X, 0, ts->abs_x_max, 0, 0); + input_set_abs_params(ts->pen_dev, ABS_MT_POSITION_Y, 0, ts->abs_y_max, 0, 0); + input_set_abs_params(ts->pen_dev, ABS_MT_PRESSURE, 0, 255, 0, 0); + input_set_abs_params(ts->pen_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); + input_set_abs_params(ts->pen_dev, ABS_MT_TRACKING_ID, 0, 255, 0, 0); + + ts->pen_dev->name = "goodix-pen"; + ts->pen_dev->id.bustype = BUS_I2C; + + ret = input_register_device(ts->pen_dev); + if (ret) + { + GTP_ERROR("Register %s input device failed", ts->pen_dev->name); + return; + } +} + +static void gtp_pen_down(s32 x, s32 y, s32 w, s32 id) +{ + struct goodix_ts_data *ts = i2c_get_clientdata(i2c_connect_client); + +#if GTP_CHANGE_X2Y + GTP_SWAP(x, y); +#endif + + + input_report_key(ts->pen_dev, BTN_TOOL_PEN, 1); +#if GTP_ICS_SLOT_REPORT + input_mt_slot(ts->pen_dev, id); + input_report_abs(ts->pen_dev, ABS_MT_POSITION_X, x); + input_report_abs(ts->pen_dev, ABS_MT_POSITION_Y, y); + input_report_key(ts->pen_dev, BTN_TOUCH, 0); + +#else + + input_report_abs(ts->pen_dev, ABS_MT_POSITION_X, x); + input_report_abs(ts->pen_dev, ABS_MT_POSITION_Y, y); + input_report_key(ts->pen_dev, BTN_TOUCH, 0); + input_mt_sync(ts->pen_dev); +#endif + GTP_DEBUG("(%d)(%d, %d)[%d]", id, x, y, w); +} + +static void gtp_pen_up(s32 id) +{ + struct goodix_ts_data *ts = i2c_get_clientdata(i2c_connect_client); + + input_report_key(ts->pen_dev, BTN_TOOL_PEN, 0); + +#if GTP_ICS_SLOT_REPORT + input_mt_slot(ts->pen_dev, id); + // input_report_abs(ts->pen_dev, ABS_MT_TRACKING_ID, -1); + input_report_key(ts->pen_dev, BTN_TOUCH, 0); +#else + + input_report_key(ts->pen_dev, BTN_TOUCH, 0); +#endif + +} +#endif + +/******************************************************* +Function: + Goodix touchscreen work function +Input: + work: work struct of goodix_workqueue +Output: + None. +*********************************************************/ +static void goodix_ts_work_func(struct work_struct *work) +{ + u8 end_cmd[3] = {GTP_READ_COOR_ADDR >> 8, GTP_READ_COOR_ADDR & 0xFF, 0}; + u8 point_data[2 + 1 + 8 * GTP_MAX_TOUCH + 1]={GTP_READ_COOR_ADDR >> 8, GTP_READ_COOR_ADDR & 0xFF}; + u8 touch_num = 0; + u8 finger = 0; + static u16 pre_touch = 0; + static u8 pre_key = 0; +#if GTP_WITH_HOVER + u8 pen_active = 0; + static u8 pre_pen = 0; +#endif + static u8 pre_finger = 0; + u8 dev_active = 0; + u8 key_value = 0; + u8* coor_data = NULL; + s32 input_x = 0; + s32 input_y = 0; + s32 input_w = 0; + s32 id = 0; + s32 i = 0; + s32 ret = -1; + struct goodix_ts_data *ts = NULL; + +#if GTP_COMPATIBLE_MODE + u8 rqst_buf[3] = {0x80, 0x43}; // for GT9XXF +#endif + +#if GTP_GESTURE_WAKEUP + u8 doze_buf[3] = {0x81, 0x4B}; +#endif + + GTP_DEBUG_FUNC(); + ts = container_of(work, struct goodix_ts_data, work); + if (ts->enter_update) + { + return; + } +#if GTP_GESTURE_WAKEUP + if (DOZE_ENABLED == doze_status) + { + ret = gtp_i2c_read(i2c_connect_client, doze_buf, 3); + GTP_DEBUG("0x814B = 0x%02X", doze_buf[2]); + if (ret > 0) + { + if ((doze_buf[2] == 'a') || (doze_buf[2] == 'b') || (doze_buf[2] == 'c') || + (doze_buf[2] == 'd') || (doze_buf[2] == 'e') || (doze_buf[2] == 'g') || + (doze_buf[2] == 'h') || (doze_buf[2] == 'm') || (doze_buf[2] == 'o') || + (doze_buf[2] == 'q') || (doze_buf[2] == 's') || (doze_buf[2] == 'v') || + (doze_buf[2] == 'w') || (doze_buf[2] == 'y') || (doze_buf[2] == 'z') || + (doze_buf[2] == 0x5E) || (doze_buf[2] == 0x3E)/* ^ */ + ) + { + if (doze_buf[2] != 0x5E) + { + GTP_INFO("Wakeup by gesture(%c), light up the screen!", doze_buf[2]); + } + else + { + GTP_INFO("Wakeup by gesture(^), light up the screen!"); + } + doze_status = DOZE_WAKEUP; + input_report_key(ts->input_dev, KEY_POWER, 1); + input_sync(ts->input_dev); + input_report_key(ts->input_dev, KEY_POWER, 0); + input_sync(ts->input_dev); + // clear 0x814B + doze_buf[2] = 0x00; + gtp_i2c_write(i2c_connect_client, doze_buf, 3); + } + else if ( (doze_buf[2] == 0xAA) || (doze_buf[2] == 0xBB) || + (doze_buf[2] == 0xAB) || (doze_buf[2] == 0xBA) ) + { + char *direction[4] = {"Right", "Down", "Up", "Left"}; + u8 type = ((doze_buf[2] & 0x0F) - 0x0A) + (((doze_buf[2] >> 4) & 0x0F) - 0x0A) * 2; + + GTP_INFO("%s slide to light up the screen!", direction[type]); + doze_status = DOZE_WAKEUP; + input_report_key(ts->input_dev, KEY_POWER, 1); + input_sync(ts->input_dev); + input_report_key(ts->input_dev, KEY_POWER, 0); + input_sync(ts->input_dev); + // clear 0x814B + doze_buf[2] = 0x00; + gtp_i2c_write(i2c_connect_client, doze_buf, 3); + } + else if (0xCC == doze_buf[2]) + { + GTP_INFO("Double click to light up the screen!"); + doze_status = DOZE_WAKEUP; + input_report_key(ts->input_dev, KEY_POWER, 1); + input_sync(ts->input_dev); + input_report_key(ts->input_dev, KEY_POWER, 0); + input_sync(ts->input_dev); + // clear 0x814B + doze_buf[2] = 0x00; + gtp_i2c_write(i2c_connect_client, doze_buf, 3); + } + else + { + // clear 0x814B + doze_buf[2] = 0x00; + gtp_i2c_write(i2c_connect_client, doze_buf, 3); + gtp_enter_doze(ts); + } + } + if (ts->use_irq) + { + gtp_irq_enable(ts); + } + return; + } +#endif + + ret = gtp_i2c_read(ts->client, point_data, 12); + if (ret < 0) + { + GTP_ERROR("I2C transfer error. errno:%d\n ", ret); + if (ts->use_irq) + { + gtp_irq_enable(ts); + } + return; + } + + finger = point_data[GTP_ADDR_LENGTH]; + +#if GTP_COMPATIBLE_MODE + // GT9XXF reques event + if ((finger == 0x00) && (CHIP_TYPE_GT9F == ts->chip_type)) // request arrived + { + ret = gtp_i2c_read(ts->client, rqst_buf, 3); + if (ret < 0) + { + GTP_ERROR("Read request status error!"); + goto exit_work_func; + } + + switch (rqst_buf[2]) + { + case GTP_RQST_CONFIG: + GTP_INFO("Request for config."); + ret = gtp_send_cfg(ts->client); + if (ret < 0) + { + GTP_ERROR("Request for config unresponded!"); + } + else + { + rqst_buf[2] = GTP_RQST_RESPONDED; + gtp_i2c_write(ts->client, rqst_buf, 3); + GTP_INFO("Request for config responded!"); + } + break; + + case GTP_RQST_BAK_REF: + GTP_INFO("Request for backup reference."); + ts->rqst_processing = 1; + ret = gtp_bak_ref_proc(ts, GTP_BAK_REF_SEND); + if (SUCCESS == ret) + { + rqst_buf[2] = GTP_RQST_RESPONDED; + gtp_i2c_write(ts->client, rqst_buf, 3); + ts->rqst_processing = 0; + GTP_INFO("Request for backup reference responded!"); + } + else + { + GTP_ERROR("Requeset for backup reference unresponed!"); + } + break; + + case GTP_RQST_RESET: + GTP_INFO("Request for reset."); + gtp_recovery_reset(ts->client); + break; + + case GTP_RQST_MAIN_CLOCK: + GTP_INFO("Request for main clock."); + ts->rqst_processing = 1; + ret = gtp_main_clk_proc(ts); + if (FAIL == ret) + { + GTP_ERROR("Request for main clock unresponded!"); + } + else + { + GTP_INFO("Request for main clock responded!"); + rqst_buf[2] = GTP_RQST_RESPONDED; + gtp_i2c_write(ts->client, rqst_buf, 3); + ts->rqst_processing = 0; + ts->clk_chk_fs_times = 0; + } + break; + + default: + GTP_INFO("Undefined request: 0x%02X", rqst_buf[2]); + rqst_buf[2] = GTP_RQST_RESPONDED; + gtp_i2c_write(ts->client, rqst_buf, 3); + break; + } + } +#endif + if (finger == 0x00) + { + if (ts->use_irq) + { + gtp_irq_enable(ts); + } + return; + } + + if((finger & 0x80) == 0) + { + goto exit_work_func; + } + + touch_num = finger & 0x0f; + if (touch_num > GTP_MAX_TOUCH) + { + goto exit_work_func; + } + + if (touch_num > 1) + { + u8 buf[8 * GTP_MAX_TOUCH] = {(GTP_READ_COOR_ADDR + 10) >> 8, (GTP_READ_COOR_ADDR + 10) & 0xff}; + + ret = gtp_i2c_read(ts->client, buf, 2 + 8 * (touch_num - 1)); + if (ret < 0) + { + GTP_ERROR("GTP read data from i2c slave device failed"); + return; + } + memcpy(&point_data[12], &buf[2], 8 * (touch_num - 1)); + } + +#if GTP_HAVE_TOUCH_KEY + key_value = point_data[3 + 8 * touch_num]; + + if(key_value || pre_key) + { + for (i = 0; i < GTP_MAX_KEY_NUM; i++) + { + #if GTP_DEBUG_ON + for (ret = 0; ret < GTP_MAX_KEY_NUM; ++ret) + { + if (key_codes[ret] == touch_key_array[i]) + { + GTP_DEBUG("Key: %s %s", key_names[ret], (key_value & (0x01 << i)) ? "Down" : "Up"); + break; + } + } + #endif + input_report_key(ts->input_dev, touch_key_array[i], key_value & (0x01<pen_dev); + } + +#endif + if (dev_active) + { + dev_active = 0; + input_sync(ts->input_dev); + } + +exit_work_func: + if(!ts->gtp_rawdiff_mode) + { + ret = gtp_i2c_write(ts->client, end_cmd, 3); + if (ret < 0) + { + GTP_INFO("I2C write end_cmd error!"); + } + } + if (ts->use_irq) + { + gtp_irq_enable(ts); + } +} + +/******************************************************* +Function: + Timer interrupt service routine for polling mode. +Input: + timer: timer struct pointer +Output: + Timer work mode. + HRTIMER_NORESTART: no restart mode +*********************************************************/ +static enum hrtimer_restart goodix_ts_timer_handler(struct hrtimer *timer) +{ + struct goodix_ts_data *ts = container_of(timer, struct goodix_ts_data, timer); + + GTP_DEBUG_FUNC(); + + queue_work(goodix_wq, &ts->work); + hrtimer_start(&ts->timer, ktime_set(0, (GTP_POLL_TIME+6)*1000000), HRTIMER_MODE_REL); + return HRTIMER_NORESTART; +} + +/******************************************************* +Function: + External interrupt service routine for interrupt mode. +Input: + irq: interrupt number. + dev_id: private data pointer +Output: + Handle Result. + IRQ_HANDLED: interrupt handled successfully +*********************************************************/ +static irqreturn_t goodix_ts_irq_handler(int irq, void *dev_id) +{ + struct goodix_ts_data *ts = dev_id; + + GTP_DEBUG_FUNC(); + + gtp_irq_disable(ts); + + queue_work(goodix_wq, &ts->work); + + return IRQ_HANDLED; +} +/******************************************************* +Function: + Synchronization. +Input: + ms: synchronization time in millisecond. +Output: + None. +*******************************************************/ +void gtp_int_sync(s32 ms) +{ + GTP_GPIO_OUTPUT(gtp_int_gpio, 0); + msleep(ms); + GTP_GPIO_AS_INT(gtp_int_gpio); +} + + +/******************************************************* +Function: + Reset chip. +Input: + ms: reset time in millisecond +Output: + None. +*******************************************************/ +void gtp_reset_guitar(struct i2c_client *client, s32 ms) +{ +#if GTP_COMPATIBLE_MODE + struct goodix_ts_data *ts = i2c_get_clientdata(client); +#endif + + GTP_DEBUG_FUNC(); + GTP_INFO("Guitar reset"); + GTP_GPIO_OUTPUT(gtp_rst_gpio, 0); // begin select I2C slave addr + msleep(ms); // T2: > 10ms + // HIGH: 0x28/0x29, LOW: 0xBA/0xBB + GTP_GPIO_OUTPUT(gtp_int_gpio, client->addr == 0x14); + + msleep(2); // T3: > 100us + GTP_GPIO_OUTPUT(gtp_rst_gpio, 1); + + msleep(6); // T4: > 5ms + + GTP_GPIO_AS_INPUT(gtp_rst_gpio); // end select I2C slave addr + +#if GTP_COMPATIBLE_MODE + if (CHIP_TYPE_GT9F == ts->chip_type) + { + return; + } +#endif + + gtp_int_sync(50); +#if GTP_ESD_PROTECT + gtp_init_ext_watchdog(client); +#endif +} + +#if GTP_GESTURE_WAKEUP +/******************************************************* +Function: + Enter doze mode for sliding wakeup. +Input: + ts: goodix tp private data +Output: + 1: succeed, otherwise failed +*******************************************************/ +static s8 gtp_enter_doze(struct goodix_ts_data *ts) +{ + s8 ret = -1; + s8 retry = 0; + u8 i2c_control_buf[3] = {(u8)(GTP_REG_SLEEP >> 8), (u8)GTP_REG_SLEEP, 8}; + + GTP_DEBUG_FUNC(); + + GTP_DEBUG("Entering gesture mode."); + while(retry++ < 5) + { + i2c_control_buf[0] = 0x80; + i2c_control_buf[1] = 0x46; + ret = gtp_i2c_write(ts->client, i2c_control_buf, 3); + if (ret < 0) + { + GTP_DEBUG("failed to set doze flag into 0x8046, %d", retry); + continue; + } + i2c_control_buf[0] = 0x80; + i2c_control_buf[1] = 0x40; + ret = gtp_i2c_write(ts->client, i2c_control_buf, 3); + if (ret > 0) + { + doze_status = DOZE_ENABLED; + GTP_INFO("Gesture mode enabled."); + return ret; + } + msleep(10); + } + GTP_ERROR("GTP send gesture cmd failed."); + return ret; +} +#else +/******************************************************* +Function: + Enter sleep mode. +Input: + ts: private data. +Output: + Executive outcomes. + 1: succeed, otherwise failed. +*******************************************************/ +static s8 gtp_enter_sleep(struct goodix_ts_data * ts) +{ + s8 ret = -1; + s8 retry = 0; + u8 i2c_control_buf[3] = {(u8)(GTP_REG_SLEEP >> 8), (u8)GTP_REG_SLEEP, 5}; + +#if GTP_COMPATIBLE_MODE + u8 status_buf[3] = {0x80, 0x44}; +#endif + + GTP_DEBUG_FUNC(); + +#if GTP_COMPATIBLE_MODE + if (CHIP_TYPE_GT9F == ts->chip_type) + { + // GT9XXF: host interact with ic + ret = gtp_i2c_read(ts->client, status_buf, 3); + if (ret < 0) + { + GTP_ERROR("failed to get backup-reference status"); + } + + if (status_buf[2] & 0x80) + { + ret = gtp_bak_ref_proc(ts, GTP_BAK_REF_STORE); + if (FAIL == ret) + { + GTP_ERROR("failed to store bak_ref"); + } + } + } +#endif + + GTP_GPIO_OUTPUT(gtp_int_gpio, 0); + msleep(5); + + while(retry++ < 5) + { + ret = gtp_i2c_write(ts->client, i2c_control_buf, 3); + if (ret > 0) + { + GTP_INFO("GTP enter sleep!"); + + return ret; + } + msleep(10); + } + GTP_ERROR("GTP send sleep cmd failed."); + return ret; +} +#endif +/******************************************************* +Function: + Wakeup from sleep. +Input: + ts: private data. +Output: + Executive outcomes. + >0: succeed, otherwise: failed. +*******************************************************/ +static s8 gtp_wakeup_sleep(struct goodix_ts_data * ts) +{ + u8 retry = 0; + s8 ret = -1; + + GTP_DEBUG_FUNC(); + +#if GTP_COMPATIBLE_MODE + if (CHIP_TYPE_GT9F == ts->chip_type) + { + u8 opr_buf[3] = {0x41, 0x80}; + + GTP_GPIO_OUTPUT(gtp_int_gpio, 1); + msleep(5); + + for (retry = 0; retry < 10; ++retry) + { + // hold ss51 & dsp + opr_buf[2] = 0x0C; + ret = gtp_i2c_write(ts->client, opr_buf, 3); + if (FAIL == ret) + { + GTP_ERROR("failed to hold ss51 & dsp!"); + continue; + } + opr_buf[2] = 0x00; + ret = gtp_i2c_read(ts->client, opr_buf, 3); + if (FAIL == ret) + { + GTP_ERROR("failed to get ss51 & dsp status!"); + continue; + } + if (0x0C != opr_buf[2]) + { + GTP_DEBUG("ss51 & dsp not been hold, %d", retry+1); + continue; + } + GTP_DEBUG("ss51 & dsp confirmed hold"); + + ret = gtp_fw_startup(ts->client); + if (FAIL == ret) + { + GTP_ERROR("failed to startup GT9XXF, process recovery"); + gtp_esd_recovery(ts->client); + } + break; + } + if (retry >= 10) + { + GTP_ERROR("failed to wakeup, processing esd recovery"); + gtp_esd_recovery(ts->client); + } + else + { + GTP_INFO("GT9XXF gtp wakeup success"); + } + return ret; + } +#endif + +#if GTP_POWER_CTRL_SLEEP + while(retry++ < 5) + { + gtp_reset_guitar(ts->client, 20); + + GTP_INFO("GTP wakeup sleep."); + return 1; + } +#else + while(retry++ < 10) + { + #if GTP_GESTURE_WAKEUP + if (DOZE_WAKEUP != doze_status) + { + GTP_INFO("Powerkey wakeup."); + } + else + { + GTP_INFO("Gesture wakeup."); + } + doze_status = DOZE_DISABLED; + gtp_irq_disable(ts); + gtp_reset_guitar(ts->client, 10); + gtp_irq_enable(ts); + + #else + GTP_GPIO_OUTPUT(gtp_int_gpio, 1); + msleep(5); + #endif + + ret = gtp_i2c_test(ts->client); + if (ret > 0) + { + GTP_INFO("GTP wakeup sleep."); + + #if (!GTP_GESTURE_WAKEUP) + { + gtp_int_sync(25); + #if GTP_ESD_PROTECT + gtp_init_ext_watchdog(ts->client); + #endif + } + #endif + + return ret; + } + gtp_reset_guitar(ts->client, 20); + } +#endif + + GTP_ERROR("GTP wakeup sleep failed."); + return ret; +} + +/******************************************************* +Function: + Initialize gtp. +Input: + ts: goodix private data +Output: + Executive outcomes. + 0: succeed, otherwise: failed +*******************************************************/ +static s32 gtp_init_panel(struct goodix_ts_data *ts) +{ + s32 ret = -1; + +#if GTP_DRIVER_SEND_CFG + s32 i = 0; + u8 check_sum = 0; + u8 opr_buf[16] = {0}; + u8 sensor_id = 0; + u8 drv_cfg_version; + u8 flash_cfg_version; + +/* if defined CONFIG_OF, parse config data from dtsi + * else parse config data form header file. + */ +#ifndef GTP_CONFIG_OF + u8 cfg_info_group0[] = CTP_CFG_GROUP0; + u8 cfg_info_group1[] = CTP_CFG_GROUP1; + u8 cfg_info_group2[] = CTP_CFG_GROUP2; + u8 cfg_info_group3[] = CTP_CFG_GROUP3; + u8 cfg_info_group4[] = CTP_CFG_GROUP4; + u8 cfg_info_group5[] = CTP_CFG_GROUP5; + + u8 *send_cfg_buf[] = {cfg_info_group0,cfg_info_group1, + cfg_info_group2, cfg_info_group3, + cfg_info_group4, cfg_info_group5}; + u8 cfg_info_len[] = { CFG_GROUP_LEN(cfg_info_group0), + CFG_GROUP_LEN(cfg_info_group1), + CFG_GROUP_LEN(cfg_info_group2), + CFG_GROUP_LEN(cfg_info_group3), + CFG_GROUP_LEN(cfg_info_group4), + CFG_GROUP_LEN(cfg_info_group5)}; + + GTP_DEBUG("Config Groups\' Lengths: %d, %d, %d, %d, %d, %d", + cfg_info_len[0], cfg_info_len[1], cfg_info_len[2], cfg_info_len[3], + cfg_info_len[4], cfg_info_len[5]); +#endif + +#if GTP_COMPATIBLE_MODE + if (CHIP_TYPE_GT9F == ts->chip_type) { + ts->fw_error = 0; + } + else +#endif + { /* check firmware */ + ret = gtp_i2c_read_dbl_check(ts->client, 0x41E4, opr_buf, 1); + if (SUCCESS == ret) + { + if (opr_buf[0] != 0xBE) + { + ts->fw_error = 1; + GTP_ERROR("Firmware error, no config sent!"); + return -1; + } + } + } + + /* read sensor id */ +#if GTP_COMPATIBLE_MODE + msleep(50); +#endif + ret = gtp_i2c_read_dbl_check(ts->client, GTP_REG_SENSOR_ID, &sensor_id, 1); + if (SUCCESS == ret) + { + if (sensor_id >= 0x06) + { + GTP_ERROR("Invalid sensor_id(0x%02X), No Config Sent!", sensor_id); + ts->pnl_init_error = 1; + return -1; + } + } + else + { + GTP_ERROR("Failed to get sensor_id, No config sent!"); + ts->pnl_init_error = 1; + return -1; + } + GTP_INFO("Sensor_ID: %d", sensor_id); + + /* parse config data*/ +#ifdef GTP_CONFIG_OF + GTP_DEBUG("Get config data from device tree."); + ret = gtp_parse_dt_cfg(&ts->client->dev, &config[GTP_ADDR_LENGTH], &ts->gtp_cfg_len, sensor_id); + if (ret < 0) { + GTP_ERROR("Failed to parse config data form device tree."); + ts->pnl_init_error = 1; + return -1; + } +#else + GTP_DEBUG("Get config data from header file."); + if ((!cfg_info_len[1]) && (!cfg_info_len[2]) && + (!cfg_info_len[3]) && (!cfg_info_len[4]) && + (!cfg_info_len[5])) + { + sensor_id = 0; + } + ts->gtp_cfg_len = cfg_info_len[sensor_id]; + memset(&config[GTP_ADDR_LENGTH], 0, GTP_CONFIG_MAX_LENGTH); + memcpy(&config[GTP_ADDR_LENGTH], send_cfg_buf[sensor_id], ts->gtp_cfg_len); +#endif + + GTP_INFO("Config group%d used,length: %d", sensor_id, ts->gtp_cfg_len); + + if (ts->gtp_cfg_len < GTP_CONFIG_MIN_LENGTH) + { + GTP_ERROR("Config Group%d is INVALID CONFIG GROUP(Len: %d)! NO Config Sent! You need to check you header file CFG_GROUP section!", sensor_id, ts->gtp_cfg_len); + ts->pnl_init_error = 1; + return -1; + } + +#if GTP_COMPATIBLE_MODE + if (ts->chip_type != CHIP_TYPE_GT9F) +#endif + { + ret = gtp_i2c_read_dbl_check(ts->client, GTP_REG_CONFIG_DATA, &opr_buf[0], 1); + if (ret == SUCCESS) { + GTP_DEBUG("Config Version: %d, 0x%02X; IC Config Version: %d, 0x%02X", + config[GTP_ADDR_LENGTH], config[GTP_ADDR_LENGTH], opr_buf[0], opr_buf[0]); + + flash_cfg_version = opr_buf[0]; + drv_cfg_version = config[GTP_ADDR_LENGTH]; + + if (flash_cfg_version < 90 && flash_cfg_version > drv_cfg_version) { + config[GTP_ADDR_LENGTH] = 0x00; + } + } else { + GTP_ERROR("Failed to get ic config version!No config sent!"); + return -1; + } + } + +#if GTP_CUSTOM_CFG + config[RESOLUTION_LOC] = (u8)GTP_MAX_WIDTH; + config[RESOLUTION_LOC + 1] = (u8)(GTP_MAX_WIDTH>>8); + config[RESOLUTION_LOC + 2] = (u8)GTP_MAX_HEIGHT; + config[RESOLUTION_LOC + 3] = (u8)(GTP_MAX_HEIGHT>>8); + + if (GTP_INT_TRIGGER == 0) //RISING + { + config[TRIGGER_LOC] &= 0xfe; + } + else if (GTP_INT_TRIGGER == 1) //FALLING + { + config[TRIGGER_LOC] |= 0x01; + } +#endif // GTP_CUSTOM_CFG + + check_sum = 0; + for (i = GTP_ADDR_LENGTH; i < ts->gtp_cfg_len; i++) + { + check_sum += config[i]; + } + config[ts->gtp_cfg_len] = (~check_sum) + 1; + +#else // driver not send config + + ts->gtp_cfg_len = GTP_CONFIG_MAX_LENGTH; + ret = gtp_i2c_read(ts->client, config, ts->gtp_cfg_len + GTP_ADDR_LENGTH); + if (ret < 0) + { + GTP_ERROR("Read Config Failed, Using Default Resolution & INT Trigger!"); + ts->abs_x_max = GTP_MAX_WIDTH; + ts->abs_y_max = GTP_MAX_HEIGHT; + ts->int_trigger_type = GTP_INT_TRIGGER; + } + +#endif // GTP_DRIVER_SEND_CFG + + if ((ts->abs_x_max == 0) && (ts->abs_y_max == 0)) + { + ts->abs_x_max = (config[RESOLUTION_LOC + 1] << 8) + config[RESOLUTION_LOC]; + ts->abs_y_max = (config[RESOLUTION_LOC + 3] << 8) + config[RESOLUTION_LOC + 2]; + ts->int_trigger_type = (config[TRIGGER_LOC]) & 0x03; + } + +#if GTP_COMPATIBLE_MODE + if (CHIP_TYPE_GT9F == ts->chip_type) + { + u8 sensor_num = 0; + u8 driver_num = 0; + u8 have_key = 0; + + have_key = (config[GTP_REG_HAVE_KEY - GTP_REG_CONFIG_DATA + 2] & 0x01); + + if (1 == ts->is_950) + { + driver_num = config[GTP_REG_MATRIX_DRVNUM - GTP_REG_CONFIG_DATA + 2]; + sensor_num = config[GTP_REG_MATRIX_SENNUM - GTP_REG_CONFIG_DATA + 2]; + if (have_key) + { + driver_num--; + } + ts->bak_ref_len = (driver_num * (sensor_num - 1) + 2) * 2 * 6; + } + else + { + driver_num = (config[CFG_LOC_DRVA_NUM] & 0x1F) + (config[CFG_LOC_DRVB_NUM]&0x1F); + if (have_key) + { + driver_num--; + } + sensor_num = (config[CFG_LOC_SENS_NUM] & 0x0F) + ((config[CFG_LOC_SENS_NUM] >> 4) & 0x0F); + ts->bak_ref_len = (driver_num * (sensor_num - 2) + 2) * 2; + } + + GTP_INFO("Drv * Sen: %d * %d(key: %d), X_MAX: %d, Y_MAX: %d, TRIGGER: 0x%02x", + driver_num, sensor_num, have_key, ts->abs_x_max,ts->abs_y_max,ts->int_trigger_type); + return 0; + } + else +#endif + { +#if GTP_DRIVER_SEND_CFG + ret = gtp_send_cfg(ts->client); + if (ret < 0) + { + GTP_ERROR("Send config error."); + } +#if GTP_COMPATIBLE_MODE + if (ts->chip_type != CHIP_TYPE_GT9F) +#endif + { + if (flash_cfg_version < 90 && flash_cfg_version > drv_cfg_version) { + check_sum = 0; + config[GTP_ADDR_LENGTH] = drv_cfg_version; + for (i = GTP_ADDR_LENGTH; i < ts->gtp_cfg_len; i++) { + check_sum += config[i]; + } + config[ts->gtp_cfg_len] = (~check_sum) + 1; + } + } + +#endif + GTP_INFO("X_MAX: %d, Y_MAX: %d, TRIGGER: 0x%02x", ts->abs_x_max,ts->abs_y_max,ts->int_trigger_type); + } + + msleep(10); + return 0; + +} + +static ssize_t gt91xx_config_read_proc(struct file *file, char __user *page, size_t size, loff_t *ppos) +{ + char *ptr = page; + char temp_data[GTP_CONFIG_MAX_LENGTH + 2] = {0x80, 0x47}; + int i; + + if (*ppos) + { + return 0; + } + ptr += sprintf(ptr, "==== GT9XX config init value====\n"); + + for (i = 0 ; i < GTP_CONFIG_MAX_LENGTH ; i++) + { + ptr += sprintf(ptr, "0x%02X ", config[i + 2]); + + if (i % 8 == 7) + ptr += sprintf(ptr, "\n"); + } + + ptr += sprintf(ptr, "\n"); + + ptr += sprintf(ptr, "==== GT9XX config real value====\n"); + gtp_i2c_read(i2c_connect_client, temp_data, GTP_CONFIG_MAX_LENGTH + 2); + for (i = 0 ; i < GTP_CONFIG_MAX_LENGTH ; i++) + { + ptr += sprintf(ptr, "0x%02X ", temp_data[i+2]); + + if (i % 8 == 7) + ptr += sprintf(ptr, "\n"); + } + *ppos += ptr - page; + return (ptr - page); +} + +static ssize_t gt91xx_config_write_proc(struct file *filp, const char __user *buffer, size_t count, loff_t *off) +{ + s32 ret = 0; + + GTP_DEBUG("write count %d\n", (int)count); + + if (count > GTP_CONFIG_MAX_LENGTH) + { + GTP_ERROR("size not match [%d:%d]\n", GTP_CONFIG_MAX_LENGTH, (int)count); + return -EFAULT; + } + + if (copy_from_user(&config[2], buffer, count)) + { + GTP_ERROR("copy from user fail\n"); + return -EFAULT; + } + + ret = gtp_send_cfg(i2c_connect_client); + + if (ret < 0) + { + GTP_ERROR("send config failed."); + } + + return count; +} +/******************************************************* +Function: + Read chip version. +Input: + client: i2c device + version: buffer to keep ic firmware version +Output: + read operation return. + 2: succeed, otherwise: failed +*******************************************************/ +s32 gtp_read_version(struct i2c_client *client, u16* version) +{ + s32 ret = -1; + u8 buf[8] = {GTP_REG_VERSION >> 8, GTP_REG_VERSION & 0xff}; + + GTP_DEBUG_FUNC(); + + ret = gtp_i2c_read(client, buf, sizeof(buf)); + if (ret < 0) + { + GTP_ERROR("GTP read version failed"); + return ret; + } + + if (version) + { + *version = (buf[7] << 8) | buf[6]; + } + if (buf[5] == 0x00) + { + GTP_INFO("IC Version: %c%c%c_%02x%02x", buf[2], buf[3], buf[4], buf[7], buf[6]); + } + else + { + GTP_INFO("IC Version: %c%c%c%c_%02x%02x", buf[2], buf[3], buf[4], buf[5], buf[7], buf[6]); + } + return ret; +} + +/******************************************************* +Function: + I2c test Function. +Input: + client:i2c client. +Output: + Executive outcomes. + 2: succeed, otherwise failed. +*******************************************************/ +static s8 gtp_i2c_test(struct i2c_client *client) +{ + u8 test[3] = {GTP_REG_CONFIG_DATA >> 8, GTP_REG_CONFIG_DATA & 0xff}; + u8 retry = 0; + s8 ret = -1; + + GTP_DEBUG_FUNC(); + + while(retry++ < 5) + { + ret = gtp_i2c_read(client, test, 3); + if (ret > 0) + { + return ret; + } + //GTP_ERROR("GTP i2c test failed time %d.",retry); + msleep(10); + } + return ret; +} + +/******************************************************* +Function: + Request gpio(INT & RST) ports. +Input: + ts: private data. +Output: + Executive outcomes. + >= 0: succeed, < 0: failed +*******************************************************/ +static s8 gtp_request_io_port(struct goodix_ts_data *ts) +{ + s32 ret = 0; + + GTP_DEBUG_FUNC(); + ret = GTP_GPIO_REQUEST(gtp_int_gpio, "GTP INT IRQ"); + if (ret < 0) + { + GTP_ERROR("Failed to request INT-GPIO:%d, ERRNO:%d", (s32)gtp_int_gpio, ret); + return -ENODEV; + } + GTP_GPIO_AS_INT(gtp_int_gpio); + ts->client->irq = gpio_to_irq(gtp_int_gpio); + + ret = GTP_GPIO_REQUEST(gtp_rst_gpio, "GTP RST PORT"); + if (ret < 0) + { + GTP_ERROR("Failed to request RST-GPIO:%d, ERRNO:%d",(s32)gtp_rst_gpio,ret); + GTP_GPIO_FREE(gtp_int_gpio); + return -ENODEV; + } + + GTP_GPIO_AS_INPUT(gtp_rst_gpio); + + gtp_reset_guitar(ts->client, 20); + + return 0; +} + +/******************************************************* +Function: + Request interrupt. +Input: + ts: private data. +Output: + Executive outcomes. + 0: succeed, -1: failed. +*******************************************************/ +static s8 gtp_request_irq(struct goodix_ts_data *ts) +{ + s32 ret = -1; + const u8 irq_table[] = GTP_IRQ_TAB; + + GTP_DEBUG_FUNC(); + GTP_DEBUG("INT trigger type:%x", ts->int_trigger_type); + + ret = request_irq(ts->client->irq, + goodix_ts_irq_handler, + irq_table[ts->int_trigger_type], + ts->client->name, + ts); + if (ret) + { + GTP_ERROR("Request IRQ failed!ERRNO:%d.", ret); + GTP_GPIO_AS_INPUT(gtp_int_gpio); + GTP_GPIO_FREE(gtp_int_gpio); + + hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + ts->timer.function = goodix_ts_timer_handler; + hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL); + return -1; + } + else + { + gtp_irq_disable(ts); + ts->use_irq = 1; + return 0; + } +} + +/******************************************************* +Function: + Request input device Function. +Input: + ts:private data. +Output: + Executive outcomes. + 0: succeed, otherwise: failed. +*******************************************************/ +static s8 gtp_request_input_dev(struct goodix_ts_data *ts) +{ + s8 ret = -1; +#if GTP_HAVE_TOUCH_KEY + u8 index = 0; +#endif + + GTP_DEBUG_FUNC(); + + ts->input_dev = input_allocate_device(); + if (ts->input_dev == NULL) + { + GTP_ERROR("Failed to allocate input device."); + return -ENOMEM; + } + + ts->input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) ; +#if GTP_ICS_SLOT_REPORT + input_mt_init_slots(ts->input_dev,16,0); // in case of "out of memory" +#else + ts->input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); +#endif + __set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit); + +#if GTP_HAVE_TOUCH_KEY + for (index = 0; index < GTP_MAX_KEY_NUM; index++) + { + input_set_capability(ts->input_dev, EV_KEY, touch_key_array[index]); + } +#endif + +#if GTP_GESTURE_WAKEUP + input_set_capability(ts->input_dev, EV_KEY, KEY_POWER); +#endif + +#if GTP_CHANGE_X2Y + GTP_SWAP(x, y); +#endif + + + input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, ts->abs_x_max, 0, 0); + input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, ts->abs_y_max, 0, 0); + input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0); + input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); + input_set_abs_params(ts->input_dev, ABS_MT_TRACKING_ID, 0, 255, 0, 0); + + input_set_abs_params(ts->input_dev, ABS_MT_TOOL_TYPE,0, MT_TOOL_MAX, 0, 0); + input_set_abs_params(ts->input_dev, ABS_MT_PRESSURE, 0, 1023, 0, 0); + + ts->input_dev->name = goodix_ts_name; + ts->input_dev->phys = goodix_input_phys; + ts->input_dev->id.bustype = BUS_I2C; + ts->input_dev->id.vendor = 0xDEAD; + ts->input_dev->id.product = 0xBEEF; + ts->input_dev->id.version = 10427; + + ret = input_register_device(ts->input_dev); + if (ret) + { + GTP_ERROR("Register %s input device failed", ts->input_dev->name); + return -ENODEV; + } + +#if GTP_WITH_HOVER + gtp_pen_init(ts); +#endif + + return 0; +} + +//************** For GT9XXF Start *************// +#if GTP_COMPATIBLE_MODE + +s32 gtp_fw_startup(struct i2c_client *client) +{ + u8 opr_buf[4]; + s32 ret = 0; + + //init sw WDT + opr_buf[0] = 0xAA; + ret = i2c_write_bytes(client, 0x8041, opr_buf, 1); + if (ret < 0) + { + return FAIL; + } + + //release SS51 & DSP + opr_buf[0] = 0x00; + ret = i2c_write_bytes(client, 0x4180, opr_buf, 1); + if (ret < 0) + { + return FAIL; + } + //int sync + gtp_int_sync(25); + + //check fw run status + ret = i2c_read_bytes(client, 0x8041, opr_buf, 1); + if (ret < 0) + { + return FAIL; + } + if(0xAA == opr_buf[0]) + { + GTP_ERROR("IC works abnormally,startup failed."); + return FAIL; + } + else + { + GTP_INFO("IC works normally, Startup success."); + opr_buf[0] = 0xAA; + i2c_write_bytes(client, 0x8041, opr_buf, 1); + return SUCCESS; + } +} + +static s32 gtp_esd_recovery(struct i2c_client *client) +{ + s32 retry = 0; + s32 ret = 0; + struct goodix_ts_data *ts; + + ts = i2c_get_clientdata(client); + + gtp_irq_disable(ts); + + GTP_INFO("GT9XXF esd recovery mode"); + for (retry = 0; retry < 5; retry++) + { + ret = gup_fw_download_proc(NULL, GTP_FL_ESD_RECOVERY); + if (FAIL == ret) + { + GTP_ERROR("esd recovery failed %d", retry+1); + continue; + } + ret = gtp_fw_startup(ts->client); + if (FAIL == ret) + { + GTP_ERROR("GT9XXF start up failed %d", retry+1); + continue; + } + break; + } + gtp_irq_enable(ts); + + if (retry >= 5) + { + GTP_ERROR("failed to esd recovery"); + return FAIL; + } + + GTP_INFO("Esd recovery successful"); + return SUCCESS; +} + +void gtp_recovery_reset(struct i2c_client *client) +{ +#if GTP_ESD_PROTECT + gtp_esd_switch(client, SWITCH_OFF); +#endif + GTP_DEBUG_FUNC(); + + gtp_esd_recovery(client); + +#if GTP_ESD_PROTECT + gtp_esd_switch(client, SWITCH_ON); +#endif +} + +static s32 gtp_bak_ref_proc(struct goodix_ts_data *ts, u8 mode) +{ + s32 ret = 0; + s32 i = 0; + s32 j = 0; + u16 ref_sum = 0; + u16 learn_cnt = 0; + u16 chksum = 0; + s32 ref_seg_len = 0; + s32 ref_grps = 0; + struct file *ref_filp = NULL; + u8 *p_bak_ref; + + ret = gup_check_fs_mounted("/data"); + if (FAIL == ret) + { + ts->ref_chk_fs_times++; + GTP_DEBUG("Ref check /data times/MAX_TIMES: %d / %d", ts->ref_chk_fs_times, GTP_CHK_FS_MNT_MAX); + if (ts->ref_chk_fs_times < GTP_CHK_FS_MNT_MAX) + { + msleep(50); + GTP_INFO("/data not mounted."); + return FAIL; + } + GTP_INFO("check /data mount timeout..."); + } + else + { + GTP_INFO("/data mounted!!!(%d/%d)", ts->ref_chk_fs_times, GTP_CHK_FS_MNT_MAX); + } + + p_bak_ref = (u8 *)kzalloc(ts->bak_ref_len, GFP_KERNEL); + + if (NULL == p_bak_ref) + { + GTP_ERROR("Allocate memory for p_bak_ref failed!"); + return FAIL; + } + + if (ts->is_950) + { + ref_seg_len = ts->bak_ref_len / 6; + ref_grps = 6; + } + else + { + ref_seg_len = ts->bak_ref_len; + ref_grps = 1; + } + ref_filp = filp_open(GTP_BAK_REF_PATH, O_RDWR | O_CREAT, 0666); + if (IS_ERR(ref_filp)) + { + GTP_ERROR("Failed to open/create %s.", GTP_BAK_REF_PATH); + if (GTP_BAK_REF_SEND == mode) + { + goto bak_ref_default; + } + else + { + goto bak_ref_exit; + } + } + + switch (mode) + { + case GTP_BAK_REF_SEND: + GTP_INFO("Send backup-reference"); + ref_filp->f_op->llseek(ref_filp, 0, SEEK_SET); + ret = ref_filp->f_op->read(ref_filp, (char*)p_bak_ref, ts->bak_ref_len, &ref_filp->f_pos); + if (ret < 0) + { + GTP_ERROR("failed to read bak_ref info from file, sending defualt bak_ref"); + goto bak_ref_default; + } + for (j = 0; j < ref_grps; ++j) + { + ref_sum = 0; + for (i = 0; i < (ref_seg_len); i += 2) + { + ref_sum += (p_bak_ref[i + j * ref_seg_len] << 8) + p_bak_ref[i+1 + j * ref_seg_len]; + } + learn_cnt = (p_bak_ref[j * ref_seg_len + ref_seg_len -4] << 8) + (p_bak_ref[j * ref_seg_len + ref_seg_len -3]); + chksum = (p_bak_ref[j * ref_seg_len + ref_seg_len -2] << 8) + (p_bak_ref[j * ref_seg_len + ref_seg_len -1]); + GTP_DEBUG("learn count = %d", learn_cnt); + GTP_DEBUG("chksum = %d", chksum); + GTP_DEBUG("ref_sum = 0x%04X", ref_sum & 0xFFFF); + // Sum(1~ref_seg_len) == 1 + if (1 != ref_sum) + { + GTP_INFO("wrong chksum for bak_ref, reset to 0x00 bak_ref"); + memset(&p_bak_ref[j * ref_seg_len], 0, ref_seg_len); + p_bak_ref[ref_seg_len + j * ref_seg_len - 1] = 0x01; + } + else + { + if (j == (ref_grps - 1)) + { + GTP_INFO("backup-reference data in %s used", GTP_BAK_REF_PATH); + } + } + } + ret = i2c_write_bytes(ts->client, GTP_REG_BAK_REF, p_bak_ref, ts->bak_ref_len); + if (FAIL == ret) + { + GTP_ERROR("failed to send bak_ref because of iic comm error"); + goto bak_ref_exit; + } + break; + + case GTP_BAK_REF_STORE: + GTP_INFO("Store backup-reference"); + ret = i2c_read_bytes(ts->client, GTP_REG_BAK_REF, p_bak_ref, ts->bak_ref_len); + if (ret < 0) + { + GTP_ERROR("failed to read bak_ref info, sending default back-reference"); + goto bak_ref_default; + } + ref_filp->f_op->llseek(ref_filp, 0, SEEK_SET); + ref_filp->f_op->write(ref_filp, (char*)p_bak_ref, ts->bak_ref_len, &ref_filp->f_pos); + break; + + default: + GTP_ERROR("invalid backup-reference request"); + break; + } + ret = SUCCESS; + goto bak_ref_exit; + +bak_ref_default: + + for (j = 0; j < ref_grps; ++j) + { + memset(&p_bak_ref[j * ref_seg_len], 0, ref_seg_len); + p_bak_ref[j * ref_seg_len + ref_seg_len - 1] = 0x01; // checksum = 1 + } + ret = i2c_write_bytes(ts->client, GTP_REG_BAK_REF, p_bak_ref, ts->bak_ref_len); + if (!IS_ERR(ref_filp)) + { + GTP_INFO("write backup-reference data into %s", GTP_BAK_REF_PATH); + ref_filp->f_op->llseek(ref_filp, 0, SEEK_SET); + ref_filp->f_op->write(ref_filp, (char*)p_bak_ref, ts->bak_ref_len, &ref_filp->f_pos); + } + if (ret == FAIL) + { + GTP_ERROR("failed to load the default backup reference"); + } + +bak_ref_exit: + + if (p_bak_ref) + { + kfree(p_bak_ref); + } + if (ref_filp && !IS_ERR(ref_filp)) + { + filp_close(ref_filp, NULL); + } + return ret; +} + + +static s32 gtp_verify_main_clk(u8 *p_main_clk) +{ + u8 chksum = 0; + u8 main_clock = p_main_clk[0]; + s32 i = 0; + + if (main_clock < 50 || main_clock > 120) + { + return FAIL; + } + + for (i = 0; i < 5; ++i) + { + if (main_clock != p_main_clk[i]) + { + return FAIL; + } + chksum += p_main_clk[i]; + } + chksum += p_main_clk[5]; + if ( (chksum) == 0) + { + return SUCCESS; + } + else + { + return FAIL; + } +} + +static s32 gtp_main_clk_proc(struct goodix_ts_data *ts) +{ + s32 ret = 0; + s32 i = 0; + s32 clk_chksum = 0; + struct file *clk_filp = NULL; + u8 p_main_clk[6] = {0}; + + ret = gup_check_fs_mounted("/data"); + if (FAIL == ret) + { + ts->clk_chk_fs_times++; + GTP_DEBUG("Clock check /data times/MAX_TIMES: %d / %d", ts->clk_chk_fs_times, GTP_CHK_FS_MNT_MAX); + if (ts->clk_chk_fs_times < GTP_CHK_FS_MNT_MAX) + { + msleep(50); + GTP_INFO("/data not mounted."); + return FAIL; + } + GTP_INFO("Check /data mount timeout!"); + } + else + { + GTP_INFO("/data mounted!!!(%d/%d)", ts->clk_chk_fs_times, GTP_CHK_FS_MNT_MAX); + } + + clk_filp = filp_open(GTP_MAIN_CLK_PATH, O_RDWR | O_CREAT, 0666); + if (IS_ERR(clk_filp)) + { + GTP_ERROR("%s is unavailable, calculate main clock", GTP_MAIN_CLK_PATH); + } + else + { + clk_filp->f_op->llseek(clk_filp, 0, SEEK_SET); + clk_filp->f_op->read(clk_filp, (char *)p_main_clk, 6, &clk_filp->f_pos); + + ret = gtp_verify_main_clk(p_main_clk); + if (FAIL == ret) + { + // recalculate main clock & rewrite main clock data to file + GTP_ERROR("main clock data in %s is wrong, recalculate main clock", GTP_MAIN_CLK_PATH); + } + else + { + GTP_INFO("main clock data in %s used, main clock freq: %d", GTP_MAIN_CLK_PATH, p_main_clk[0]); + filp_close(clk_filp, NULL); + goto update_main_clk; + } + } + +#if GTP_ESD_PROTECT + gtp_esd_switch(ts->client, SWITCH_OFF); +#endif + ret = gup_clk_calibration(); + gtp_esd_recovery(ts->client); + +#if GTP_ESD_PROTECT + gtp_esd_switch(ts->client, SWITCH_ON); +#endif + + GTP_INFO("calibrate main clock: %d", ret); + if (ret < 50 || ret > 120) + { + GTP_ERROR("wrong main clock: %d", ret); + goto exit_main_clk; + } + + // Sum{0x8020~0x8025} = 0 + for (i = 0; i < 5; ++i) + { + p_main_clk[i] = ret; + clk_chksum += p_main_clk[i]; + } + p_main_clk[5] = 0 - clk_chksum; + + if (!IS_ERR(clk_filp)) + { + GTP_DEBUG("write main clock data into %s", GTP_MAIN_CLK_PATH); + clk_filp->f_op->llseek(clk_filp, 0, SEEK_SET); + clk_filp->f_op->write(clk_filp, (char *)p_main_clk, 6, &clk_filp->f_pos); + filp_close(clk_filp, NULL); + } + +update_main_clk: + ret = i2c_write_bytes(ts->client, GTP_REG_MAIN_CLK, p_main_clk, 6); + if (FAIL == ret) + { + GTP_ERROR("update main clock failed!"); + return FAIL; + } + return SUCCESS; + +exit_main_clk: + if (!IS_ERR(clk_filp)) + { + filp_close(clk_filp, NULL); + } + return FAIL; +} + + +s32 gtp_gt9xxf_init(struct i2c_client *client) +{ + s32 ret = 0; + + ret = gup_fw_download_proc(NULL, GTP_FL_FW_BURN); + if (FAIL == ret) + { + return FAIL; + } + + ret = gtp_fw_startup(client); + if (FAIL == ret) + { + return FAIL; + } + return SUCCESS; +} + +void gtp_get_chip_type(struct goodix_ts_data *ts) +{ + u8 opr_buf[10] = {0x00}; + s32 ret = 0; + + msleep(10); + + ret = gtp_i2c_read_dbl_check(ts->client, GTP_REG_CHIP_TYPE, opr_buf, 10); + + if (FAIL == ret) + { + GTP_ERROR("Failed to get chip-type, set chip type default: GOODIX_GT9"); + ts->chip_type = CHIP_TYPE_GT9; + return; + } + + if (!memcmp(opr_buf, "GOODIX_GT9", 10)) + { + ts->chip_type = CHIP_TYPE_GT9; + } + else // GT9XXF + { + ts->chip_type = CHIP_TYPE_GT9F; + } + GTP_INFO("Chip Type: %s", (ts->chip_type == CHIP_TYPE_GT9) ? "GOODIX_GT9" : "GOODIX_GT9F"); +} +#endif //For GT9XXF End// + +/* + * Devices Tree support, +*/ +#ifdef GTP_CONFIG_OF +/** + * gtp_parse_dt - parse platform infomation form devices tree. + */ +static void gtp_parse_dt(struct device *dev) +{ + struct device_node *np = dev->of_node; + u32 temp_val; + int ret = 0; + + gtp_int_gpio = of_get_named_gpio(np, "irq-gpio", 0); + gtp_rst_gpio = of_get_named_gpio(np, "reset-gpio", 0); + + ret = of_property_read_u32(np, "rotation", &temp_val); + if (!ret) { + rotation = temp_val; + } else { + rotation = 0; + GTP_ERROR("cannot get rotation value of touchscreen"); + } +} + +/** + * gtp_parse_dt_cfg - parse config data from devices tree. + * @dev: device that this driver attached. + * @cfg: pointer of the config array. + * @cfg_len: pointer of the config length. + * @sid: sensor id. + * Return: 0-succeed, -1-faileds + */ +int gtp_parse_dt_cfg(struct device *dev, u8 *cfg, int *cfg_len, u8 sid) +{ + struct device_node *np = dev->of_node; + struct property *prop; + char cfg_name[18]; + + snprintf(cfg_name, sizeof(cfg_name), "goodix,cfg-group%d", sid); + prop = of_find_property(np, cfg_name, cfg_len); + if (!prop || !prop->value || *cfg_len == 0 || *cfg_len > GTP_CONFIG_MAX_LENGTH) { + return -1;/* failed */ + } else { + memcpy(cfg, prop->value, *cfg_len); + return 0; + } +} + +/** + * gtp_power_switch - power switch . + * @on: 1-switch on, 0-switch off. + * return: 0-succeed, -1-faileds + */ +static int gtp_power_switch(struct i2c_client *client, int on) +{ + static struct regulator *vdd_ana; + static struct regulator *vcc_i2c; + int ret; + + if (!vdd_ana) { + vdd_ana = regulator_get(&client->dev, "vdd_ana"); + if (IS_ERR(vdd_ana)) { + GTP_ERROR("regulator get of vdd_ana failed"); + ret = PTR_ERR(vdd_ana); + vdd_ana = NULL; + return ret; + } + } + + if (!vcc_i2c) { + vcc_i2c = regulator_get(&client->dev, "vcc_i2c"); + if (IS_ERR(vcc_i2c)) { + GTP_ERROR("regulator get of vcc_i2c failed"); + ret = PTR_ERR(vcc_i2c); + vcc_i2c = NULL; + goto ERR_GET_VCC; + } + } + + if (on) { + GTP_DEBUG("GTP power on."); + ret = regulator_enable(vdd_ana); + udelay(2); + ret = regulator_enable(vcc_i2c); + } else { + GTP_DEBUG("GTP power off."); + ret = regulator_disable(vcc_i2c); + udelay(2); + ret = regulator_disable(vdd_ana); + } + return ret; + +ERR_GET_VCC: + regulator_put(vdd_ana); + return ret; +} +#endif + +/******************************************************* +Function: + I2c probe. +Input: + client: i2c device struct. + id: device id. +Output: + Executive outcomes. + 0: succeed. +*******************************************************/ +static int goodix_ts_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + s32 ret = -1; + struct goodix_ts_data *ts; + u16 version_info; + + GTP_DEBUG_FUNC(); + + //do NOT remove these logs + GTP_INFO("GTP Driver Version: %s", GTP_DRIVER_VERSION); + GTP_INFO("GTP I2C Address: 0x%02x", client->addr); + + goodix_wq = create_singlethread_workqueue("goodix_wq"); + if (!goodix_wq) { + GTP_ERROR("Create workqueue failed."); + ret = -ENOMEM; + goto err_create_workqueue; + } + +#if GTP_ESD_PROTECT + INIT_DELAYED_WORK(>p_esd_check_work, gtp_esd_check_func); + gtp_esd_check_workqueue = create_workqueue("gtp_esd_check"); + if (!gtp_esd_check_workqueue) { + GTP_ERROR("Create esd workqueue failed."); + ret = -ENOMEM; + goto err_create_esd_work; + } +#endif + + i2c_connect_client = client; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) + { + GTP_ERROR("I2C check functionality failed."); + ret = -ENODEV; + goto err_i2c_check_func; + } + ts = kzalloc(sizeof(*ts), GFP_KERNEL); + if (ts == NULL) + { + GTP_ERROR("Alloc GFP_KERNEL memory failed."); + ret = -ENOMEM; + goto err_mem_alloc; + } + +#ifdef GTP_CONFIG_OF /* device tree support */ + if (client->dev.of_node) { + gtp_parse_dt(&client->dev); + } + ret = gtp_power_switch(client, 1); + if (ret) { + GTP_ERROR("GTP power on failed."); + ret = -EINVAL; + goto err_power_switch; + } +#else /* use gpio defined in gt9xx.h */ + gtp_rst_gpio = GTP_RST_PORT; + gtp_int_gpio = GTP_INT_PORT; +#endif + + INIT_WORK(&ts->work, goodix_ts_work_func); + ts->client = client; + spin_lock_init(&ts->irq_lock); // 2.6.39 later + // ts->irq_lock = SPIN_LOCK_UNLOCKED; // 2.6.39 & before +#if GTP_ESD_PROTECT + ts->clk_tick_cnt = 2 * HZ; // HZ: clock ticks in 1 second generated by system + GTP_DEBUG("Clock ticks for an esd cycle: %d", ts->clk_tick_cnt); + spin_lock_init(&ts->esd_lock); + // ts->esd_lock = SPIN_LOCK_UNLOCKED; +#endif + i2c_set_clientdata(client, ts); + ts->gtp_rawdiff_mode = 0; + ret = gtp_request_io_port(ts); + if (ret < 0) + { + GTP_ERROR("GTP request IO port failed."); + goto err_request_io_port; + } + +#if GTP_COMPATIBLE_MODE + gtp_get_chip_type(ts); + if (CHIP_TYPE_GT9F == ts->chip_type) + { + ret = gtp_gt9xxf_init(ts->client); + if (FAIL == ret) + { + GTP_INFO("Failed to init GT9XXF."); + } + } +#endif + + ret = gtp_i2c_test(client); + if (ret < 0) + { + GTP_ERROR("I2C communication ERROR!"); + goto err_chip_init; + } + + ret = gtp_read_version(client, &version_info); + if (ret < 0) + { + GTP_ERROR("Read version failed."); + goto err_chip_init; + } + + ret = gtp_init_panel(ts); + if (ret < 0) + { + GTP_ERROR("GTP init panel failed."); + ts->abs_x_max = GTP_MAX_WIDTH; + ts->abs_y_max = GTP_MAX_HEIGHT; + ts->int_trigger_type = GTP_INT_TRIGGER; + goto err_chip_init; + } + + // Create proc file system + gt91xx_config_proc = proc_create(GT91XX_CONFIG_PROC_FILE, 0666, NULL, &config_proc_ops); + if (gt91xx_config_proc == NULL) + { + GTP_ERROR("create_proc_entry %s failed\n", GT91XX_CONFIG_PROC_FILE); + } + else + { + GTP_INFO("create proc entry %s success", GT91XX_CONFIG_PROC_FILE); + } + +#if GTP_ESD_PROTECT + gtp_esd_switch(client, SWITCH_ON); +#endif + +#if GTP_AUTO_UPDATE + ret = gup_init_update_proc(ts); + if (ret < 0) + { + GTP_ERROR("Create update thread error."); + } +#endif + + ret = gtp_request_input_dev(ts); + if (ret < 0) + { + GTP_ERROR("GTP request input dev failed"); + goto err_request_input_dev; + } + + ret = gtp_request_irq(ts); + if (ret < 0) + { + GTP_INFO("GTP works in polling mode."); + } + else + { + GTP_INFO("GTP works in interrupt mode."); + } + + if (ts->use_irq) + { + gtp_irq_enable(ts); +#if GTP_GESTURE_WAKEUP + enable_irq_wake(client->irq); +#endif + } + + /* register suspend and resume fucntion*/ + gtp_register_powermanger(ts); + +#if GTP_CREATE_WR_NODE + init_wr_node(client); +#endif + return 0; + +err_request_input_dev: +#if GTP_ESD_PROTECT + gtp_esd_switch(client, SWITCH_OFF); +#endif +err_chip_init: + GTP_GPIO_FREE(gtp_int_gpio); + GTP_GPIO_FREE(gtp_rst_gpio); +err_request_io_port: +#ifdef GTP_CONFIG_OF + gtp_power_switch(client, 0); +err_power_switch: +#endif + kfree(ts); +err_mem_alloc: +err_i2c_check_func: +#if GTP_ESD_PROTECT + destroy_workqueue(gtp_esd_check_workqueue); +err_create_esd_work: +#endif + destroy_workqueue(goodix_wq); +err_create_workqueue: + return ret; + +} + + +/******************************************************* +Function: + Goodix touchscreen driver release function. +Input: + client: i2c device struct. +Output: + Executive outcomes. 0---succeed. +*******************************************************/ +static int goodix_ts_remove(struct i2c_client *client) +{ + struct goodix_ts_data *ts = i2c_get_clientdata(client); + + GTP_DEBUG_FUNC(); + + gtp_unregister_powermanger(ts); + +#if GTP_CREATE_WR_NODE + uninit_wr_node(); +#endif + +#if GTP_ESD_PROTECT + destroy_workqueue(gtp_esd_check_workqueue); +#endif + + if (ts) + { + if (ts->use_irq) + { + GTP_GPIO_AS_INPUT(gtp_int_gpio); + GTP_GPIO_FREE(gtp_int_gpio); + free_irq(client->irq, ts); + } + else + { + hrtimer_cancel(&ts->timer); + } + } + + GTP_INFO("GTP driver removing..."); + i2c_set_clientdata(client, NULL); + if (ts) + { + input_unregister_device(ts->input_dev); + kfree(ts); + } + + if (goodix_wq) + destroy_workqueue(goodix_wq); + + return 0; +} + + +/******************************************************* +Function: + Early suspend function. +Input: + h: early_suspend struct. +Output: + None. +*******************************************************/ +static void goodix_ts_suspend(struct goodix_ts_data *ts) +{ + s8 ret = -1; + + GTP_DEBUG_FUNC(); + if (ts->enter_update) { + return; + } + GTP_INFO("System suspend."); + + ts->gtp_is_suspend = 1; +#if GTP_ESD_PROTECT + gtp_esd_switch(ts->client, SWITCH_OFF); +#endif + +#if GTP_GESTURE_WAKEUP + ret = gtp_enter_doze(ts); +#else + if (ts->use_irq) + { + gtp_irq_disable(ts); + } + else + { + hrtimer_cancel(&ts->timer); + } + ret = gtp_enter_sleep(ts); +#endif + if (ret < 0) + { + GTP_ERROR("GTP early suspend failed."); + } + // to avoid waking up while not sleeping + // delay 48 + 10ms to ensure reliability + msleep(58); +} + +/******************************************************* +Function: + Late resume function. +Input: + h: early_suspend struct. +Output: + None. +*******************************************************/ +static void goodix_ts_resume(struct goodix_ts_data *ts) +{ + s8 ret = -1; + GTP_DEBUG_FUNC(); + if (ts->enter_update) { + return; + } + GTP_INFO("System resume."); + + ret = gtp_wakeup_sleep(ts); +#if GTP_GESTURE_WAKEUP + doze_status = DOZE_DISABLED; +#endif + + if (ret < 0) + { + GTP_ERROR("GTP later resume failed."); + } +#if (GTP_COMPATIBLE_MODE) + if (CHIP_TYPE_GT9F == ts->chip_type) + { + // do nothing + } + else +#endif + { + gtp_send_cfg(ts->client); + } + + if (ts->use_irq) + { + gtp_irq_enable(ts); + } + else + { + hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL); + } + + ts->gtp_is_suspend = 0; +#if GTP_ESD_PROTECT + gtp_esd_switch(ts->client, SWITCH_ON); +#endif +} + + +#if defined(CONFIG_FB) +/* frame buffer notifier block control the suspend/resume procedure */ +static int gtp_fb_notifier_callback(struct notifier_block *noti, unsigned long event, void *data) +{ + struct fb_event *ev_data = data; + struct goodix_ts_data *ts = container_of(noti, struct goodix_ts_data, notifier); + int *blank; + + if (ev_data && ev_data->data && event == FB_EVENT_BLANK && ts) { + blank = ev_data->data; + if (*blank == FB_BLANK_UNBLANK) { + GTP_DEBUG("Resume by fb notifier."); + goodix_ts_resume(ts); + + } + else if (*blank == FB_BLANK_POWERDOWN) { + GTP_DEBUG("Suspend by fb notifier."); + goodix_ts_suspend(ts); + } + } + + return 0; +} +#elif defined(CONFIG_PM) +/* bus control the suspend/resume procedure */ +static int gtp_pm_suspend(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct goodix_ts_data *ts = i2c_get_clientdata(client); + + if (ts) { + GTP_DEBUG("Suspend by i2c pm."); + goodix_ts_suspend(ts); + } + + return 0; +} +static int gtp_pm_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct goodix_ts_data *ts = i2c_get_clientdata(client); + + if (ts) { + GTP_DEBUG("Resume by i2c pm."); + goodix_ts_resume(ts); + } + + return 0; +} + +static struct dev_pm_ops gtp_pm_ops = { + .suspend = gtp_pm_suspend, + .resume = gtp_pm_resume, +}; + +#elif defined(CONFIG_HAS_EARLYSUSPEND) +/* earlysuspend module the suspend/resume procedure */ +static void gtp_early_suspend(struct early_suspend *h) +{ + struct goodix_ts_data *ts = container_of(h, struct goodix_ts_data, early_suspend); + + if (ts) { + GTP_DEBUG("Suspend by earlysuspend module."); + goodix_ts_suspend(ts); + } +} +static void gtp_early_resume(struct early_suspend *h) +{ + struct goodix_ts_data *ts = container_of(h, struct goodix_ts_data, early_suspend); + + if (ts) { + GTP_DEBUG("Resume by earlysuspend module."); + goodix_ts_resume(ts); + } +} +#endif + +static int gtp_register_powermanger(struct goodix_ts_data *ts) +{ +#if defined(CONFIG_FB) + ts->notifier.notifier_call = gtp_fb_notifier_callback; + fb_register_client(&ts->notifier); + +#elif defined(CONFIG_HAS_EARLYSUSPEND) + ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; + ts->early_suspend.suspend = goodix_ts_early_suspend; + ts->early_suspend.resume = goodix_ts_late_resume; + register_early_suspend(&ts->early_suspend); +#endif + + return 0; +} + +static int gtp_unregister_powermanger(struct goodix_ts_data *ts) +{ +#if defined(CONFIG_FB) + fb_unregister_client(&ts->notifier); + +#elif defined(CONFIG_HAS_EARLYSUSPEND) + unregister_early_suspend(&ts->early_suspend); +#endif + return 0; +} + +/* end */ + +#if GTP_ESD_PROTECT +s32 gtp_i2c_read_no_rst(struct i2c_client *client, u8 *buf, s32 len) +{ + struct i2c_msg msgs[2]; + s32 ret=-1; + s32 retries = 0; + + GTP_DEBUG_FUNC(); + + msgs[0].flags = !I2C_M_RD; + msgs[0].addr = client->addr; + msgs[0].len = GTP_ADDR_LENGTH; + msgs[0].buf = &buf[0]; + //msgs[0].scl_rate = 300 * 1000; // for Rockchip, etc. + + msgs[1].flags = I2C_M_RD; + msgs[1].addr = client->addr; + msgs[1].len = len - GTP_ADDR_LENGTH; + msgs[1].buf = &buf[GTP_ADDR_LENGTH]; + //msgs[1].scl_rate = 300 * 1000; + + while(retries < 5) + { + ret = i2c_transfer(client->adapter, msgs, 2); + if(ret == 2)break; + retries++; + } + if ((retries >= 5)) + { + GTP_ERROR("I2C Read: 0x%04X, %d bytes failed, errcode: %d!", (((u16)(buf[0] << 8)) | buf[1]), len-2, ret); + } + return ret; +} + +s32 gtp_i2c_write_no_rst(struct i2c_client *client,u8 *buf,s32 len) +{ + struct i2c_msg msg; + s32 ret = -1; + s32 retries = 0; + + GTP_DEBUG_FUNC(); + + msg.flags = !I2C_M_RD; + msg.addr = client->addr; + msg.len = len; + msg.buf = buf; + //msg.scl_rate = 300 * 1000; // for Rockchip, etc + + while(retries < 5) + { + ret = i2c_transfer(client->adapter, &msg, 1); + if (ret == 1)break; + retries++; + } + if((retries >= 5)) + { + GTP_ERROR("I2C Write: 0x%04X, %d bytes failed, errcode: %d!", (((u16)(buf[0] << 8)) | buf[1]), len-2, ret); + } + return ret; +} +/******************************************************* +Function: + switch on & off esd delayed work +Input: + client: i2c device + on: SWITCH_ON / SWITCH_OFF +Output: + void +*********************************************************/ +void gtp_esd_switch(struct i2c_client *client, s32 on) +{ + struct goodix_ts_data *ts; + + ts = i2c_get_clientdata(client); + spin_lock(&ts->esd_lock); + + if (SWITCH_ON == on) // switch on esd + { + if (!ts->esd_running) + { + ts->esd_running = 1; + spin_unlock(&ts->esd_lock); + GTP_INFO("Esd started"); + queue_delayed_work(gtp_esd_check_workqueue, >p_esd_check_work, ts->clk_tick_cnt); + } else { + spin_unlock(&ts->esd_lock); + } + } + else // switch off esd + { + if (ts->esd_running) + { + ts->esd_running = 0; + spin_unlock(&ts->esd_lock); + GTP_INFO("Esd cancelled"); + cancel_delayed_work_sync(>p_esd_check_work); + } + else + { + spin_unlock(&ts->esd_lock); + } + } +} + +/******************************************************* +Function: + Initialize external watchdog for esd protect +Input: + client: i2c device. +Output: + result of i2c write operation. + 1: succeed, otherwise: failed +*********************************************************/ +static s32 gtp_init_ext_watchdog(struct i2c_client *client) +{ + u8 opr_buffer[3] = {0x80, 0x41, 0xAA}; + GTP_DEBUG("[Esd]Init external watchdog"); + return gtp_i2c_write_no_rst(client, opr_buffer, 3); +} + +/******************************************************* +Function: + Esd protect function. + External watchdog added by meta, 2013/03/07 +Input: + work: delayed work +Output: + None. +*******************************************************/ +static void gtp_esd_check_func(struct work_struct *work) +{ + s32 i; + s32 ret = -1; + struct goodix_ts_data *ts = NULL; + u8 esd_buf[5] = {0x80, 0x40}; + + GTP_DEBUG_FUNC(); + + ts = i2c_get_clientdata(i2c_connect_client); + + if (ts->gtp_is_suspend || ts->enter_update) + { + GTP_INFO("Esd suspended!"); + return; + } + + for (i = 0; i < 3; i++) + { + ret = gtp_i2c_read_no_rst(ts->client, esd_buf, 4); + + GTP_DEBUG("[Esd]0x8040 = 0x%02X, 0x8041 = 0x%02X", esd_buf[2], esd_buf[3]); + if ((ret < 0)) + { + // IIC communication problem + continue; + } + else + { + if ((esd_buf[2] == 0xAA) || (esd_buf[3] != 0xAA)) + { + // IC works abnormally.. + u8 chk_buf[4] = {0x80, 0x40}; + + gtp_i2c_read_no_rst(ts->client, chk_buf, 4); + GTP_DEBUG("[Check]0x8040 = 0x%02X, 0x8041 = 0x%02X", chk_buf[2], chk_buf[3]); + if ((chk_buf[2] == 0xAA) || (chk_buf[3] != 0xAA)) + { + i = 3; + break; + } + else + { + continue; + } + } + else + { + // IC works normally, Write 0x8040 0xAA, feed the dog + esd_buf[2] = 0xAA; + gtp_i2c_write_no_rst(ts->client, esd_buf, 3); + break; + } + } + } + if (i >= 3) + { + #if GTP_COMPATIBLE_MODE + if (CHIP_TYPE_GT9F == ts->chip_type) + { + if (ts->rqst_processing) + { + GTP_INFO("Request processing, no esd recovery"); + } + else + { + GTP_ERROR("IC working abnormally! Process esd recovery."); + esd_buf[0] = 0x42; + esd_buf[1] = 0x26; + esd_buf[2] = 0x01; + esd_buf[3] = 0x01; + esd_buf[4] = 0x01; + gtp_i2c_write_no_rst(ts->client, esd_buf, 5); + msleep(50); + #ifdef GTP_CONFIG_OF + gtp_power_switch(ts->client, 0); + msleep(20); + gtp_power_switch(ts->client, 1); + msleep(20); + #endif + gtp_esd_recovery(ts->client); + } + } + else + #endif + { + GTP_ERROR("IC working abnormally! Process reset guitar."); + esd_buf[0] = 0x42; + esd_buf[1] = 0x26; + esd_buf[2] = 0x01; + esd_buf[3] = 0x01; + esd_buf[4] = 0x01; + gtp_i2c_write_no_rst(ts->client, esd_buf, 5); + msleep(50); + #ifdef GTP_CONFIG_OF + gtp_power_switch(ts->client, 0); + msleep(20); + gtp_power_switch(ts->client, 1); + msleep(20); + #endif + gtp_reset_guitar(ts->client, 50); + msleep(50); + gtp_send_cfg(ts->client); + } + } + + if(!ts->gtp_is_suspend) + { + queue_delayed_work(gtp_esd_check_workqueue, >p_esd_check_work, ts->clk_tick_cnt); + } + else + { + GTP_INFO("Esd suspended!"); + } + return; +} +#endif + +#ifdef GTP_CONFIG_OF +static const struct of_device_id goodix_match_table[] = { + {.compatible = "goodix,gt9xx",}, + { }, +}; +#endif + +static const struct i2c_device_id goodix_ts_id[] = { + { GTP_I2C_NAME, 0 }, + { } +}; + +static struct i2c_driver goodix_ts_driver = { + .probe = goodix_ts_probe, + .remove = goodix_ts_remove, + .id_table = goodix_ts_id, + .driver = { + .name = GTP_I2C_NAME, + .owner = THIS_MODULE, +#ifdef GTP_CONFIG_OF + .of_match_table = goodix_match_table, +#endif +#if !defined(CONFIG_FB) && defined(CONFIG_PM) + .pm = >p_pm_ops, +#endif + }, +}; + +module_i2c_driver(goodix_ts_driver); + +MODULE_DESCRIPTION("GTP Series Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/amlogic/input/touchscreen/gt9xx/gt9xx.h b/drivers/amlogic/input/touchscreen/gt9xx/gt9xx.h new file mode 100644 index 0000000000000..abb8fd32f929b --- /dev/null +++ b/drivers/amlogic/input/touchscreen/gt9xx/gt9xx.h @@ -0,0 +1,333 @@ +/* + * Goodix GT9xx touchscreen driver + * + * Copyright (C) 2010 - 2016 Goodix. Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be a reference + * to you, when you are integrating the GOODiX's CTP IC into your system, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * Version: 2.4.0.1 + * Release Date: 2016/10/26 + */ + +#ifndef _GOODIX_GT9XX_H_ +#define _GOODIX_GT9XX_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_OF +#include +#include +#endif +#ifdef CONFIG_FB +#include +#include +#endif +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif + + +#define GTP_CONFIG_OF + +//***************************PART1:ON/OFF define******************************* +#define GTP_CUSTOM_CFG 0 +#define GTP_CHANGE_X2Y 0 +#define GTP_X_REVERSE_ENABLE 1 +#define GTP_Y_REVERSE_ENABLE 1 +#define GTP_DRIVER_SEND_CFG 1 //driver send config +#define GTP_HAVE_TOUCH_KEY 0 +#define GTP_POWER_CTRL_SLEEP 0 //power off when suspend +#define GTP_ICS_SLOT_REPORT 1 // slot protocol + +#define GTP_AUTO_UPDATE 0 // auto update fw by .bin file as default +#define GTP_HEADER_FW_UPDATE 0 // auto update fw by gtp_default_FW in gt9xx_firmware.h, function together with GTP_AUTO_UPDATE +#define GTP_AUTO_UPDATE_CFG 0 // auto update config by .cfg file, function together with GTP_AUTO_UPDATE + +#define GTP_COMPATIBLE_MODE 0 // compatible with GT9XXF + +#define GTP_CREATE_WR_NODE 1 +#define GTP_ESD_PROTECT 1 // esd protection with a cycle of 2 seconds + +#define GTP_WITH_HOVER 1 //pen surrport hover or not 1:enable 0 disable + +#define GTP_GESTURE_WAKEUP 1 // gesture wakeup + +#define GTP_DEBUG_ON 1 +#define GTP_DEBUG_ARRAY_ON 1 +#define GTP_DEBUG_FUNC_ON 1 + +#if GTP_COMPATIBLE_MODE +typedef enum +{ + CHIP_TYPE_GT9 = 0, + CHIP_TYPE_GT9F = 1, +} CHIP_TYPE_T; +#endif + +struct goodix_ts_data { + spinlock_t irq_lock; + struct i2c_client *client; + struct input_dev *input_dev; + struct hrtimer timer; + struct work_struct work; + s32 irq_is_disable; + s32 use_irq; + u16 abs_x_max; + u16 abs_y_max; + u8 max_touch_num; + u8 int_trigger_type; + u8 green_wake_mode; + u8 enter_update; + u8 gtp_is_suspend; + u8 gtp_rawdiff_mode; + int gtp_cfg_len; + u8 fw_error; + u8 pnl_init_error; + +#if defined(CONFIG_FB) + struct notifier_block notifier; +#elif defined(CONFIG_HAS_EARLYSUSPEND) + struct early_suspend early_suspend; +#endif + +#if GTP_WITH_HOVER + struct input_dev *pen_dev; +#endif + +#if GTP_ESD_PROTECT + spinlock_t esd_lock; + u8 esd_running; + s32 clk_tick_cnt; +#endif +#if GTP_COMPATIBLE_MODE + u16 bak_ref_len; + s32 ref_chk_fs_times; + s32 clk_chk_fs_times; + CHIP_TYPE_T chip_type; + u8 rqst_processing; + u8 is_950; +#endif + +}; + +extern u16 show_len; +extern u16 total_len; +extern int gtp_rst_gpio; +extern int gtp_int_gpio; + +//*************************** PART2:TODO define ********************************** +// STEP_1(REQUIRED): Define Configuration Information Group(s) +// Sensor_ID Map: +/* sensor_opt1 sensor_opt2 Sensor_ID + GND GND 0 + VDDIO GND 1 + NC GND 2 + GND NC/300K 3 + VDDIO NC/300K 4 + NC NC/300K 5 +*/ +// TODO: define your own default or for Sensor_ID == 0 config here. +// The predefined one is just a sample config, which is not suitable for your tp in most cases. +#define CTP_CFG_GROUP0 {\ + 0x00,0x80,0x07,0xB0,0x04,0x0A,0x0D,0x00,0x01,0x08,0x28,\ + 0x05,0x50,0x32,0x03,0x05,0x00,0x00,0x00,0x00,0x00,0x00,\ + 0x00,0x00,0x00,0x00,0x00,0x90,0x30,0xAA,0x17,0x15,0x31,\ + 0x0D,0x00,0x00,0x01,0x99,0x04,0x24,0x00,0x00,0x00,0x00,\ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,\ + 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,0x01,0x04,0x05,0x06,0x07,0x08,0x09,0x0C,\ + 0x0D,0x0E,0x0F,0x10,0x11,0x14,0x15,0x16,0x17,0x18,0x19,\ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,\ + 0x02,0x04,0x06,0x07,0x08,0x0A,0x0C,0x0D,0x0E,0x0F,0x10,\ + 0x11,0x12,0x13,0x14,0x19,0x1B,0x1C,0x1E,0x1F,0x20,0x21,\ + 0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0xFF,0xFF,\ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x4D,0x01\ + } + +// TODO: define your config for Sensor_ID == 1 here, if needed +#define CTP_CFG_GROUP1 {\ + } + +// TODO: define your config for Sensor_ID == 2 here, if needed +#define CTP_CFG_GROUP2 {\ + 0x00,0x80,0x07,0xB0,0x04,0x0A,0x0D,0x00,0x01,0x08,0x28,\ + 0x05,0x50,0x32,0x03,0x05,0x00,0x00,0x00,0x00,0x00,0x00,\ + 0x00,0x00,0x00,0x00,0x00,0x90,0x30,0xAA,0x17,0x15,0x31,\ + 0x0D,0x00,0x00,0x01,0x99,0x04,0x24,0x00,0x00,0x00,0x00,\ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,\ + 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,0x01,0x04,0x05,0x06,0x07,0x08,0x09,0x0C,\ + 0x0D,0x0E,0x0F,0x10,0x11,0x14,0x15,0x16,0x17,0x18,0x19,\ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,\ + 0x02,0x04,0x06,0x07,0x08,0x0A,0x0C,0x0D,0x0E,0x0F,0x10,\ + 0x11,0x12,0x13,0x14,0x19,0x1B,0x1C,0x1E,0x1F,0x20,0x21,\ + 0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0xFF,0xFF,\ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x4D,0x01\ + } + +// TODO: define your config for Sensor_ID == 3 here, if needed +#define CTP_CFG_GROUP3 {\ +} +// TODO: define your config for Sensor_ID == 4 here, if needed +#define CTP_CFG_GROUP4 {\ + } + +// TODO: define your config for Sensor_ID == 5 here, if needed +#define CTP_CFG_GROUP5 {\ + } + +// STEP_2(REQUIRED): Customize your I/O ports & I/O operations +#define GTP_RST_PORT 16//S5PV210_GPJ3(6) +#define GTP_INT_PORT 17//S5PV210_GPH1(3) + +#define GTP_GPIO_AS_INPUT(pin) do{\ + gpio_direction_input(pin);\ + }while(0) +#define GTP_GPIO_AS_INT(pin) do{\ + GTP_GPIO_AS_INPUT(pin);\ + }while(0) +#define GTP_GPIO_GET_VALUE(pin) gpio_get_value(pin) +#define GTP_GPIO_OUTPUT(pin,level) gpio_direction_output(pin,level) +#define GTP_GPIO_REQUEST(pin, label) gpio_request(pin, label) +#define GTP_GPIO_FREE(pin) gpio_free(pin) +#define GTP_IRQ_TAB {IRQ_TYPE_EDGE_RISING, IRQ_TYPE_EDGE_FALLING, IRQ_TYPE_LEVEL_LOW, IRQ_TYPE_LEVEL_HIGH} + +// STEP_3(optional): Specify your special config info if needed +#if GTP_CUSTOM_CFG + #define GTP_MAX_HEIGHT 800 + #define GTP_MAX_WIDTH 480 + #define GTP_INT_TRIGGER 0 // 0: Rising 1: Falling +#else + #define GTP_MAX_HEIGHT 4096 + #define GTP_MAX_WIDTH 4096 + #define GTP_INT_TRIGGER 1 +#endif +#define GTP_MAX_TOUCH 10 + +// STEP_4(optional): If keys are available and reported as keys, config your key info here +#if GTP_HAVE_TOUCH_KEY + #define GTP_KEY_TAB {KEY_MENU, KEY_HOME, KEY_BACK, KEY_HOMEPAGE, KEY_F1, KEY_F2, KEY_F3} +#endif + +//***************************PART3:OTHER define********************************* +#define GTP_DRIVER_VERSION "V2.4.0.1<2016/10/26>" +#define GTP_I2C_NAME "GT9XX-TS" +#define GT91XX_CONFIG_PROC_FILE "gt9xx_config" +#define GTP_POLL_TIME 10 +#define GTP_ADDR_LENGTH 2 +#define GTP_CONFIG_MIN_LENGTH 186 +#define GTP_CONFIG_MAX_LENGTH 240 +#define FAIL 0 +#define SUCCESS 1 +#define SWITCH_OFF 0 +#define SWITCH_ON 1 + +//******************** For GT9XXF Start **********************// +#define GTP_REG_BAK_REF 0x99D0 +#define GTP_REG_MAIN_CLK 0x8020 +#define GTP_REG_CHIP_TYPE 0x8000 +#define GTP_REG_HAVE_KEY 0x804E +#define GTP_REG_MATRIX_DRVNUM 0x8069 +#define GTP_REG_MATRIX_SENNUM 0x806A + +#define GTP_FL_FW_BURN 0x00 +#define GTP_FL_ESD_RECOVERY 0x01 +#define GTP_FL_READ_REPAIR 0x02 + +#define GTP_BAK_REF_SEND 0 +#define GTP_BAK_REF_STORE 1 +#define CFG_LOC_DRVA_NUM 29 +#define CFG_LOC_DRVB_NUM 30 +#define CFG_LOC_SENS_NUM 31 + +#define GTP_CHK_FW_MAX 40 +#define GTP_CHK_FS_MNT_MAX 300 +#define GTP_BAK_REF_PATH "/data/gtp_ref.bin" +#define GTP_MAIN_CLK_PATH "/data/gtp_clk.bin" +#define GTP_RQST_CONFIG 0x01 +#define GTP_RQST_BAK_REF 0x02 +#define GTP_RQST_RESET 0x03 +#define GTP_RQST_MAIN_CLOCK 0x04 +#define GTP_RQST_RESPONDED 0x00 +#define GTP_RQST_IDLE 0xFF + +//******************** For GT9XXF End **********************// +// Registers define +#define GTP_READ_COOR_ADDR 0x814E +#define GTP_REG_SLEEP 0x8040 +#define GTP_REG_SENSOR_ID 0x814A +#define GTP_REG_CONFIG_DATA 0x8047 +#define GTP_REG_VERSION 0x8140 + +#define RESOLUTION_LOC 3 +#define TRIGGER_LOC 8 + +#define CFG_GROUP_LEN(p_cfg_grp) (sizeof(p_cfg_grp) / sizeof(p_cfg_grp[0])) +// Log define +#define GTP_INFO(fmt,arg...) printk("<<-GT9XX-INFO->> "fmt"\n",##arg) +#define GTP_ERROR(fmt,arg...) printk("<<-GT9XX-ERROR->> "fmt"\n",##arg) +#define GTP_DEBUG(fmt,arg...) do{\ + if(GTP_DEBUG_ON)\ + printk("<<-GT9XX-DEBUG->> [%d]"fmt"\n",__LINE__, ##arg);\ + }while(0) +#define GTP_DEBUG_ARRAY(array, num) do{\ + s32 i;\ + u8* a = array;\ + if(GTP_DEBUG_ARRAY_ON)\ + {\ + printk("<<-GT9XX-DEBUG-ARRAY->>\n");\ + for (i = 0; i < (num); i++)\ + {\ + printk("%02x ", (a)[i]);\ + if ((i + 1 ) %10 == 0)\ + {\ + printk("\n");\ + }\ + }\ + printk("\n");\ + }\ + }while(0) +#define GTP_DEBUG_FUNC() do{\ + if(GTP_DEBUG_FUNC_ON)\ + printk("<<-GT9XX-FUNC->> Func:%s@Line:%d\n",__func__,__LINE__);\ + }while(0) +#define GTP_SWAP(x, y) do{\ + typeof(x) z = x;\ + x = y;\ + y = z;\ + }while (0) + +//*****************************End of Part III******************************** +#ifdef CONFIG_OF +int gtp_parse_dt_cfg(struct device *dev, u8 *cfg, int *cfg_len, u8 sid); +#endif +#endif /* _GOODIX_GT9XX_H_ */ diff --git a/drivers/amlogic/input/touchscreen/gt9xx/gt9xx_cfg.h b/drivers/amlogic/input/touchscreen/gt9xx/gt9xx_cfg.h new file mode 100644 index 0000000000000..7dd04ea5e6edb --- /dev/null +++ b/drivers/amlogic/input/touchscreen/gt9xx/gt9xx_cfg.h @@ -0,0 +1,66 @@ +/* drivers/input/touchscreen/gt9xx_cfg.h + * + * 2010 - 2013 Goodix Technology. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be a reference + * to you, when you are integrating the GOODiX's CTP IC into your system, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + */ + +#ifndef _GOODIX_GT9XX_CFG_H_ +#define _GOODIX_GT9XX_CFG_H_ + +/* CFG for GT911 */ +u8 gtp_dat_gt11[] = { + /* <1200, 1920>*/ + #include "WGJ89006B_GT911_Config_20140625_085816_0X43.cfg" +}; + +u8 gtp_dat_gt9110[] = { + /* <1200, 1920>*/ + #include "GT9110P(2020)V71_Config_20201028_170326.cfg" +}; + +u8 gtp_dat_gt9111[] = { + #include "HLS-0102-1398V1-1060-GT911_Config_20201204_V66.cfg" +}; + +u8 gtp_dat_8_9[] = { + /* TODO:Puts your update firmware data here! */ + /* <1920, 1200> 8.9 */ + /* #include "WGJ89006B_GT9271_Config_20140625_085816_0X41.cfg" */ + /* #include "WGJ10162_GT9271_Config_20140820_182456.cfg" + #include "WGJ10162B_GT9271_1060_Config_20140821_1341110X42.cfg"*/ + #include "WGJ10162B_GT9271_1920_1200.cfg" +}; + +u8 gtp_dat_8_9_1[] = { + #include "GT9271_Config_20170526.cfg" +}; + +u8 gtp_dat_9_7[] = { + /* <1536, 2048> 9.7 */ + #include "GT9110P_Config_20160217_1526_2048_97.cfg" +}; + +u8 gtp_dat_10_1[] = { + /* TODO:Puts your update firmware data here! */ + /* <1200, 1920> 10.1 */ + #include "WGJ10187_GT9271_Config_20140623_104014_0X41.cfg" +}; + +u8 gtp_dat_7[] = { + /* TODO:Puts your update firmware data here! */ + /* <1024, 600> 7.0 */ + #include "WGJ10187_GT910_Config_20140623_104014_0X41.cfg" +}; + +#endif /* _GOODIX_GT9XX_CFG_H_ */ diff --git a/drivers/amlogic/input/touchscreen/gt9xx/gt9xx_firmware.h b/drivers/amlogic/input/touchscreen/gt9xx/gt9xx_firmware.h new file mode 100644 index 0000000000000..8e0b1ad73be51 --- /dev/null +++ b/drivers/amlogic/input/touchscreen/gt9xx/gt9xx_firmware.h @@ -0,0 +1,2344 @@ +/* + * drivers/amlogic/input/touchscreen/goodix_gt9xx/gt9xx_firmware.h + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef _GT9XX_FIRMWARE_H_ +#define _GT9XX_FIRMWARE_H_ + +#if GTP_HEADER_FW_UPDATE +unsigned char gtp_default_FW[] = +{ + //TODO:Puts your update firmware data here! +}; +#endif + +/* +*[HW INFO]00900600 +*[PID]910 +*[VID]1010 +*[GENERATED]2013/08/27 20:59:13 +*/ +#if GTP_COMPATIBLE_MODE +unsigned char gtp_default_FW_fl[] = { +/* 0x00,0x90,0x06,0x00,0x39,0x31,0x30,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x80,0x00, + 0x55,0x40,0xf8,0x86,0x98,0x71,0x69,0xf0,0x0c,0xc1,0x78,0x1e,0xd2,0x48,0x88,0x58, + 0xa3,0x41,0xd2,0xeb,0xb2,0x63,0x32,0xe0,0x1d,0xc9,0xf8,0x75,0x15,0x6e,0x01,0x8d, + 0x05,0x02,0xf9,0x87,0x18,0x7a,0x12,0x6b,0x4d,0x21,0x17,0xd5,0x94,0x6d,0x09,0x0d, + 0x87,0x03,0x4f,0xc2,0x13,0x0b,0x09,0x7b,0x4d,0x4b,0xf9,0x74,0x99,0xe8,0x38,0xa8, + 0x3d,0xc9,0xa2,0x4d,0x13,0x74,0xab,0x47,0xe3,0xe5,0xee,0x49,0xdf,0xd2,0x00,0x54, + 0x8b,0xfb,0x48,0x94,0x1f,0x67,0x8b,0x8e,0xbe,0xe4,0xce,0x59,0x55,0x46,0xbe,0x86, + 0x40,0x06,0x98,0xb8,0x77,0xa0,0x85,0x9e,0x2b,0x05,0x99,0xfd,0xb1,0xd4,0xf6,0xb9, + 0x40,0x9c,0x50,0x1d,0x4e,0x1a,0x0d,0x82,0xe9,0x9a,0x5d,0x17,0xba,0x86,0x47,0xac, + 0x2c,0x48,0x26,0x6e,0x59,0x38,0x10,0xda,0x0f,0x4c,0x15,0xce,0xda,0x40,0x9a,0x3c, + 0x2f,0x49,0xd0,0x18,0xba,0x2f,0x20,0x3a,0x55,0x69,0xea,0x5c,0x4f,0x62,0x98,0xcc, + 0x0f,0x7a,0xfb,0x8f,0x99,0x52,0x17,0x7d,0x2f,0xb4,0x91,0xcf,0xde,0x32,0x48,0x6c, + 0xaf,0x48,0x83,0x51,0xdb,0x24,0x9b,0x29,0xd9,0x49,0xda,0xc2,0x2e,0x29,0xa5,0xcc, + 0x28,0x7a,0x6d,0x4e,0x1e,0xd7,0x04,0xc8,0xa1,0x4f,0x8a,0x74,0x39,0x55,0xf0,0xa7, + 0xb2,0x61,0xcf,0x1d,0x5d,0xa0,0x5c,0x41,0xa2,0xfc,0x2f,0x1e,0x1b,0x62,0x79,0xa2, + 0xb9,0xf5,0x44,0xc9,0xf3,0x59,0x55,0x44,0x82,0x7f,0xc5,0x40,0xdc,0x6d,0xac,0x19, + 0x8f,0x26,0xb6,0xb5,0xa4,0xe2,0x03,0xd6,0x83,0xde,0xfb,0x6d,0x93,0x1e,0x04,0x80, + 0x78,0xf8,0x88,0x83,0x91,0xba,0x2c,0xc0,0xd0,0x58,0x9c,0xb7,0x63,0x58,0xde,0xb0, + 0x26,0xe9,0x6a,0x64,0x85,0x3e,0xe5,0xc2,0xef,0x34,0x5c,0x69,0x02,0xaa,0x4f,0x28, + 0x82,0x11,0x7b,0x67,0x32,0x38,0x64,0xd3,0x6e,0x37,0x48,0x25,0xc7,0x77,0x02,0x1d, + 0x24,0xe6,0x65,0xb8,0xb7,0x22,0x64,0xc3,0x6f,0x36,0xa8,0x48,0xc1,0x06,0x22,0x10, + 0x21,0x5d,0x8e,0x84,0x36,0x1d,0x74,0xa0,0x61,0x4f,0xe4,0x60,0x50,0x10,0x34,0xe2, + 0xd7,0x1a,0x06,0x36,0xd3,0xca,0x5c,0xb0,0x79,0xf8,0x4f,0xe7,0x5d,0x84,0x7b,0xe9, + 0x6a,0xdc,0xfc,0xb6,0x82,0x92,0x8b,0x97,0x6d,0xd0,0xdd,0xf1,0x3a,0x35,0x16,0xd1, + 0xcb,0x3d,0x7e,0x37,0x5a,0x1d,0xca,0xc0,0x42,0xa8,0xe3,0x50,0x9b,0x54,0xc6,0x69, + 0x14,0xb3,0x86,0xca,0xc4,0x3e,0x3f,0xfb,0xec,0x44,0xdf,0x82,0x37,0xc3,0x79,0x69, + 0x44,0x1c,0x3a,0x8c,0x9a,0x7b,0x66,0x9f,0xf8,0xf5,0x43,0x0c,0x12,0xea,0x37,0x37, + 0xc3,0xd3,0x0f,0x21,0x59,0x35,0xbe,0xfa,0x64,0x06,0x68,0x29,0xc1,0x20,0x51,0xfc, + 0xcc,0xb0,0x14,0x4a,0x65,0x72,0xbf,0xf3,0x7c,0xf7,0x0c,0x86,0xea,0xee,0x38,0xf1, + 0xdb,0xcf,0x1f,0xcc,0x46,0x93,0x68,0xd4,0x44,0x83,0xa8,0x4d,0x93,0x3f,0x5b,0xab, + 0x13,0x73,0xdd,0xcf,0x30,0x0c,0xbc,0x70,0x8e,0xd4,0xd8,0xd5,0x33,0xcc,0x39,0xf1, + 0x62,0x34,0xd0,0xa3,0xcc,0x91,0xfb,0x96,0xd9,0xd5,0x81,0x4d,0x11,0x7d,0x29,0x1d, + 0xa8,0x57,0xf1,0xf4,0x34,0x99,0x7f,0x13,0x1e,0xd6,0xe1,0xc4,0xd8,0x3f,0x20,0x02, + 0x04,0xc0,0xff,0x26,0x67,0xa0,0x20,0x62,0xc4,0xc6,0x2f,0xd9,0xb5,0x1f,0x28,0x12, + 0x05,0xc1,0x68,0xdf,0xca,0x5c,0x3c,0xb5,0x64,0x56,0x82,0xc9,0xa2,0xa3,0x79,0xfa, + 0x84,0x82,0x7e,0x07,0xe3,0xae,0xac,0xd1,0x25,0x19,0x4a,0xa3,0xa1,0x01,0x29,0x8f, + 0x85,0x83,0x22,0x77,0xcd,0xa5,0x8d,0xcc,0x86,0x30,0xa7,0x31,0x34,0x5c,0xa5,0xb2, + 0x3d,0xb5,0x1f,0x2d,0x9b,0x52,0x50,0xd5,0x0e,0xd5,0xd0,0xb8,0xbf,0x95,0x10,0x39, + 0x6f,0x88,0xb6,0xb4,0x57,0x98,0xc2,0x8d,0xc8,0x68,0xbf,0x4f,0x51,0xc6,0xa1,0xe3, + 0x39,0x0b,0xe9,0x43,0x1e,0x58,0x7d,0xda,0xf5,0x1d,0xee,0x87,0xd4,0x6d,0x7f,0x31, + 0xe7,0x78,0xdb,0x67,0x54,0x08,0xee,0xec,0xa4,0xc3,0x7d,0x04,0xbb,0xe8,0x22,0x0a, + 0x0c,0xc8,0xae,0x79,0x7f,0x37,0x62,0x59,0x54,0x42,0x4d,0xd0,0x5a,0x01,0x2a,0x1a, + 0x0d,0xc9,0xe7,0x19,0x9d,0xe7,0x8e,0x5a,0x45,0x19,0x65,0x62,0x2e,0xee,0x23,0x96, + 0x8c,0x8a,0xdb,0xf2,0x90,0xe8,0xf4,0xd5,0x2d,0xac,0x02,0x0b,0xab,0x5f,0xb6,0xda, + 0x8d,0x8b,0x6b,0xfe,0xa1,0xad,0x94,0xeb,0x4c,0x6a,0xe4,0x0b,0x15,0x01,0x1c,0x4c, + 0xef,0x0f,0x42,0x3d,0xbd,0x2f,0x0b,0x1b,0x3a,0xda,0x32,0xce,0xec,0x67,0x14,0x77, + 0xc7,0xe7,0x95,0x4d,0x10,0xbc,0x2e,0xe8,0x4f,0x60,0xae,0xda,0x3c,0xef,0x93,0xcf, + 0xac,0x14,0x04,0xcb,0xbc,0x34,0x7b,0xb2,0x41,0x63,0xf7,0x8d,0x86,0xac,0x7a,0x28, + 0xbf,0xe1,0xd5,0x77,0x10,0x09,0x2b,0x0b,0x4f,0x49,0x6c,0x8c,0x5b,0x64,0x01,0x82, + 0x4f,0xb4,0xc4,0x84,0x6a,0x1d,0x90,0xec,0xbb,0xed,0x7a,0x5b,0x76,0x2b,0xac,0x92, + 0x94,0x1c,0x82,0x12,0x1e,0x43,0x94,0x9f,0x1e,0xc9,0xe5,0x57,0x90,0x0e,0xda,0x87, + 0xa4,0xf7,0x3d,0x65,0xb2,0x99,0xde,0xd4,0x64,0x05,0x85,0x23,0xd9,0xd7,0xc9,0xb4, + 0x16,0x1e,0x72,0x3a,0xb3,0x98,0xe2,0xb2,0xe3,0x9a,0x51,0xc4,0x9f,0x05,0xa4,0x63, + 0x00,0x1f,0x2c,0x86,0x32,0x9d,0x54,0x68,0x67,0x57,0xf2,0xde,0x5f,0x6e,0x36,0xe9, + 0x21,0x96,0xfb,0x25,0xb3,0x3e,0x26,0x64,0x75,0x18,0x10,0x85,0x0b,0x73,0xee,0xfe, + 0x4d,0xd2,0xdf,0x37,0x86,0x17,0x99,0x90,0x9a,0xcd,0xf3,0xcf,0xdf,0x65,0xc9,0x93, + 0xe3,0x33,0xd8,0x66,0xc7,0x18,0x67,0xf1,0x54,0x7a,0x02,0x84,0x83,0x7e,0xc2,0xad, + 0x2d,0xf8,0x4b,0x7f,0x8e,0x28,0x20,0xd8,0xee,0xdc,0xec,0xac,0xcf,0x51,0x2f,0x45, + 0xce,0x9d,0x56,0x6e,0x35,0xb6,0xb2,0x4a,0x92,0xd6,0xe7,0x47,0x1a,0xf8,0xdd,0x89, + 0xa4,0xd5,0x4f,0xa5,0x3e,0xb2,0x3b,0x49,0x6e,0xde,0xe5,0x25,0xfd,0x7a,0x3a,0xe9, + 0x23,0xfe,0x07,0xa1,0x3a,0xce,0x05,0x9c,0x4e,0xbe,0x85,0x3d,0x1f,0xe0,0xb6,0xf6, + 0xe6,0xff,0x42,0xac,0xd5,0x5d,0xe5,0x9a,0xee,0xca,0xd6,0x7c,0xfe,0xf4,0x10,0xdc, + 0x4c,0x98,0xd0,0xeb,0xdc,0xb4,0xcc,0xc6,0x7f,0x18,0xde,0xfb,0xb7,0x0c,0xf0,0x3b, + 0xac,0x6f,0xfd,0xd2,0x9f,0xb7,0x7f,0xfe,0xdd,0xb5,0xf1,0x1e,0xc6,0x01,0xbc,0x28, + 0x23,0x92,0x3e,0xad,0x54,0xce,0xe8,0x88,0xd3,0xb1,0xea,0x84,0x70,0x79,0x00,0x40, + 0x3f,0x8d,0xda,0x06,0xa3,0xb9,0xaa,0xdf,0xa9,0x71,0xa8,0x20,0xd5,0xb2,0x58,0xba, + 0xa0,0xfe,0x9a,0x15,0x17,0x22,0x08,0xbd,0x4a,0x5a,0xd9,0xd4,0x59,0xa3,0x7f,0x2c, + 0xda,0x40,0xe0,0x45,0xa2,0xdf,0xfd,0xbe,0xc3,0xc0,0xc8,0xcc,0x35,0xa0,0xe5,0x82, + 0xbd,0x0b,0x98,0xd5,0xdb,0x38,0x45,0x47,0xbd,0xbc,0xc0,0xdc,0x34,0x71,0xfa,0xbf, + 0x8d,0x82,0xd6,0x26,0xa9,0x99,0xe8,0x80,0x46,0x69,0x77,0xa5,0xbb,0x4e,0x11,0xbd, + 0x66,0x0c,0x08,0xf4,0x19,0xd8,0x85,0x06,0xbc,0xd8,0x5c,0x06,0xb8,0x4f,0x41,0x01, + 0xde,0xfb,0x6d,0xce,0x91,0x56,0x2c,0x13,0x31,0x5d,0x3d,0xf7,0x84,0x6e,0x4c,0xb9, + 0xa4,0xca,0xb1,0x4c,0x13,0x48,0xf5,0xee,0xc2,0x07,0x19,0xd5,0x92,0x25,0x00,0x17, + 0x34,0xbc,0x5f,0x7a,0x79,0x08,0x28,0x8d,0xbf,0x0a,0x18,0xcc,0x3e,0x6e,0x34,0x31, + 0x86,0x12,0x18,0x9e,0x99,0x22,0x4a,0x04,0x48,0x41,0x5e,0xb9,0x1a,0x9a,0x95,0x72, + 0xab,0xd7,0xdb,0x24,0xb8,0x98,0x43,0xc1,0x69,0x08,0xb3,0x74,0x79,0xb5,0xd0,0x8f, + 0x88,0x6b,0xb3,0x98,0x97,0xa1,0x21,0xd1,0xa2,0x84,0x5f,0xbb,0x97,0x96,0x20,0x4d, + 0x09,0x4c,0xc1,0x0f,0xd6,0x37,0x6e,0xed,0xbb,0xed,0x82,0x16,0xd5,0xc1,0x92,0xae, + 0x38,0xb6,0x4a,0x3f,0xa0,0x36,0x48,0x72,0x4d,0x4e,0xd2,0x6c,0xa7,0x27,0xc1,0x6d, + 0x6b,0x15,0x1e,0x3b,0xeb,0x25,0x6b,0x58,0x6b,0xf1,0x1b,0xe9,0xf8,0x9f,0xf1,0xa6, + 0x06,0x89,0x16,0xc9,0x7a,0xb0,0x4b,0x1b,0x34,0x0d,0xfb,0x6c,0xdd,0x6c,0x7a,0xa8, + 0xdd,0x19,0xdd,0x86,0xd7,0x31,0xd4,0x00,0x53,0x5d,0x1f,0x2e,0x71,0xd0,0x34,0x63, + 0x11,0x17,0xd7,0x26,0x06,0xc7,0x14,0xb4,0xbd,0x60,0xf6,0x36,0x93,0x6a,0x06,0x05, + 0x8a,0x62,0x40,0x04,0x83,0x26,0xea,0x66,0x2a,0x63,0xaf,0x5a,0xf6,0x59,0x7f,0x79, + 0x00,0x91,0xd0,0x47,0xc6,0x33,0x7d,0x03,0xd2,0x5e,0xa5,0x4a,0xd2,0xd3,0x34,0x39, + 0x46,0x61,0xf8,0x32,0x34,0x37,0x66,0x1f,0x51,0x9f,0xee,0x17,0x7d,0x36,0xd0,0x0f, + 0xc2,0x0e,0xf2,0x10,0xbe,0xc3,0xb9,0x00,0xe3,0x4a,0xe7,0x33,0x9a,0xff,0x0c,0xef, + 0xed,0x54,0x82,0xa7,0xf0,0xc9,0xed,0x0e,0x6f,0xab,0x85,0x4d,0xf4,0x75,0x12,0x27, + 0x90,0xbc,0x85,0xd1,0x1a,0xf8,0x43,0x13,0x71,0x5f,0x1d,0x55,0x8f,0x7f,0x7e,0x0c, + 0x0a,0x03,0x59,0x34,0x3e,0x1b,0xe9,0x98,0x3c,0x1a,0xcf,0x5d,0x3c,0x7c,0x1b,0xd8, + 0x2d,0xed,0x50,0xea,0xb6,0xbf,0x66,0x3c,0x10,0x34,0x64,0x54,0x52,0xb4,0x3f,0x76, + 0x27,0xbc,0x41,0xce,0xfe,0x21,0x47,0x44,0x01,0x6b,0x95,0xdf,0xcb,0xd1,0x1a,0x69, + 0xfd,0xba,0x8f,0xdd,0xb5,0xf9,0x1a,0xd8,0xb3,0x5d,0xe0,0x7a,0x10,0xd8,0xfc,0x0f, + 0xe8,0x95,0x06,0x6c,0x08,0x7e,0x81,0x6c,0x48,0xee,0xd4,0xd3,0x39,0x78,0xb1,0x5c, + 0x00,0x93,0x02,0x58,0x19,0xcc,0xb2,0x6a,0x3d,0x55,0xdc,0x03,0xa7,0xf7,0x4f,0xc4, + 0x4b,0xd1,0x97,0xb7,0x35,0x93,0x6f,0x79,0x01,0x74,0xd1,0x69,0xd8,0x6d,0x6f,0xdc, + 0x98,0xa4,0xc7,0xd9,0x12,0xf0,0xdb,0x8b,0x00,0x75,0x86,0x10,0xbd,0xb2,0x06,0x2b, + 0x38,0x0b,0x77,0x26,0xb5,0xd2,0x0e,0x0b,0x2f,0xcf,0x74,0xa0,0x02,0xe6,0x7c,0x17, + 0xa4,0x2e,0x44,0x84,0x19,0xa9,0x6e,0x41,0x27,0x48,0x43,0xd4,0xd0,0x93,0x66,0x32, + 0xe8,0xc0,0xf8,0x05,0xd0,0x6f,0xb1,0x11,0x49,0x64,0x91,0x76,0x75,0x68,0xbf,0x23, + 0xbe,0xc1,0x6b,0xff,0xa6,0x68,0x19,0xd9,0x2c,0xcc,0x11,0xbe,0x57,0x64,0x70,0x82, + 0x1e,0x79,0xb9,0xab,0xf3,0x5b,0x20,0x32,0xcb,0x32,0xfa,0x76,0xa9,0x10,0x3e,0xf2, + 0x1d,0xc6,0x68,0x15,0xdf,0x38,0x30,0x8d,0x41,0xc6,0xba,0x89,0xbe,0x8f,0xcd,0xd1, + 0x96,0x8e,0xda,0x00,0x48,0xae,0x73,0x88,0xc0,0xc5,0x39,0xe3,0xf4,0xec,0x09,0xe1, + 0xb4,0x8a,0xff,0x35,0xff,0xaa,0x28,0x34,0x19,0x47,0x55,0xe8,0xd4,0x07,0x72,0xe5, + 0xad,0x77,0x27,0x06,0x7b,0xbf,0x28,0x28,0xde,0xc2,0xeb,0x4c,0x7f,0x4a,0x62,0x1e, + 0x85,0x17,0xa4,0x7c,0x5c,0x89,0x63,0xdb,0x8b,0xc3,0x56,0x4d,0x00,0x1f,0x1d,0x26, + 0x03,0x7c,0x4b,0x82,0x1e,0xae,0xb6,0x58,0xf4,0xa6,0xea,0xd3,0x39,0x15,0x4b,0xa9, + 0xbe,0x86,0xd3,0x1d,0xdd,0x26,0xbf,0x1b,0xd3,0x59,0xe1,0x3d,0x6e,0x42,0x3b,0xb7, + 0xe9,0x41,0x9d,0x7e,0x86,0xee,0x8d,0x01,0xc3,0x4a,0x41,0xab,0x83,0x31,0xaa,0xfa, + 0x91,0x56,0xd1,0x2d,0x14,0xef,0xd6,0xe8,0x5f,0xc7,0x36,0x0d,0x50,0x83,0x3a,0xb4, + 0xfd,0xc9,0xb3,0x1a,0x98,0xad,0x72,0xab,0xd8,0x33,0x5c,0x6d,0xde,0x1a,0x5c,0xa6, + 0xda,0x14,0xbb,0x63,0x9e,0xef,0x39,0x10,0x13,0xc0,0x99,0x53,0xde,0x8f,0x35,0x06, + 0x06,0xeb,0x84,0x92,0xd5,0xab,0x46,0x4a,0xc5,0x2f,0xd3,0x56,0xf4,0xef,0x3d,0x16, + 0x5c,0xfc,0x96,0x7e,0x3a,0xfe,0xdb,0x41,0x51,0xca,0x3f,0xc9,0x15,0xb1,0x1b,0xaa, + 0x07,0x67,0x79,0x71,0xa4,0x7d,0x99,0x4b,0xdb,0x1f,0xab,0x17,0x66,0xfa,0x77,0x7a, + 0xcd,0x72,0xcd,0x95,0xe0,0xbe,0xe1,0xd5,0x16,0xc3,0x7d,0x17,0xc5,0xfb,0xe6,0x2a, + 0x55,0x59,0x24,0x66,0x35,0x36,0xb4,0x42,0x27,0x54,0xe2,0x84,0x1e,0xf9,0x68,0x46, + 0x03,0x8e,0x0b,0x16,0x33,0x98,0x34,0x62,0x8c,0xbf,0xb4,0xfe,0x71,0xf6,0x89,0x51, + 0xa6,0x9e,0x1a,0xb4,0xf5,0xda,0x0b,0x27,0xe0,0xd5,0x88,0x9c,0x7b,0xc0,0xcb,0xb5, + 0x28,0x11,0x17,0x53,0x95,0x05,0x91,0x61,0xd3,0xdf,0xb9,0x88,0x54,0x47,0xe6,0x2a, + 0x93,0x35,0x8c,0x5e,0x60,0xb9,0x8e,0x51,0xe1,0x55,0x34,0x68,0x66,0xe3,0xab,0xe9, + 0x1d,0x96,0xce,0x9c,0x1e,0xb4,0x45,0x52,0x1a,0x14,0xcc,0x56,0xdc,0xe2,0xb2,0x69, + 0xaa,0xb9,0x9f,0x8b,0x39,0x58,0x50,0x50,0x0d,0x4c,0x69,0x5b,0xbe,0xfc,0x0f,0x47, + 0x9e,0x40,0x50,0xd8,0xb3,0xba,0xc2,0x7c,0x14,0xad,0x62,0x49,0xce,0x30,0x66,0x8a, + 0x32,0xd1,0xde,0x5e,0xc1,0x11,0xf2,0x98,0x85,0xb6,0xd6,0x09,0x9f,0x63,0xd4,0x3a, + 0x23,0x86,0x68,0xe0,0x34,0x41,0x00,0x2a,0x5c,0xa6,0xee,0xda,0x4c,0xef,0x25,0x2d, + 0x9d,0xe5,0xab,0x88,0x60,0xb4,0xb7,0x4b,0xdc,0x5e,0xcb,0xcf,0xae,0xd3,0xc9,0x3d, + 0x9c,0xf5,0x54,0x80,0x3f,0xbf,0xc5,0x6b,0x87,0xd2,0x47,0xef,0x58,0xbe,0xa8,0x38, + 0xe1,0x1b,0xcd,0x44,0x92,0x24,0x5a,0xbd,0x4e,0x06,0xd6,0x03,0xf1,0x25,0xe0,0x0d, + 0x13,0x4e,0xa2,0x91,0x1f,0xab,0x20,0xe0,0x1d,0x5a,0x3e,0xc0,0x59,0x7a,0xa3,0xe7, + 0x05,0xb0,0xc9,0x67,0xd3,0x2e,0xd6,0xa3,0x40,0xda,0xaf,0xa3,0x88,0x79,0xa1,0x81, + 0x04,0xa3,0x0d,0xfd,0x15,0x6c,0x39,0xd7,0x64,0x2d,0x5a,0x53,0x2e,0x6a,0x02,0xa6, + 0x31,0xd6,0x98,0x5d,0xb3,0x46,0xa8,0xe2,0xc2,0x9e,0x2f,0x5a,0x3e,0x26,0x36,0x84, + 0x05,0xed,0x4a,0x36,0x9e,0x47,0x20,0xf2,0xc3,0xbf,0xdd,0x07,0x6b,0x6a,0xf9,0xa9, + 0x1a,0xc7,0x21,0xd5,0xb0,0xa4,0x69,0xe3,0x2c,0x0b,0xca,0x5e,0x50,0x65,0x5a,0x23, + 0x7c,0x45,0x0d,0xd3,0xd7,0x21,0x61,0xf3,0x2d,0x2a,0x89,0x6c,0x8b,0x61,0xaa,0x1c, + 0x8d,0x28,0xe2,0x0e,0x43,0x25,0x70,0x39,0x49,0x28,0x16,0xc4,0x94,0xa8,0xf5,0xf5, + 0x01,0x52,0x72,0x7a,0x94,0xaf,0x3a,0x65,0xe8,0xc3,0x8e,0x5a,0xae,0x72,0xf8,0xf4, + 0x9f,0xb1,0xc9,0x10,0xab,0x3e,0x49,0x38,0x6f,0x4c,0x83,0x34,0x80,0x71,0x79,0xf0, + 0x06,0x49,0x89,0xdd,0x95,0xa0,0x9c,0xd1,0xa6,0x04,0x8b,0x5b,0xad,0x24,0xdc,0xbc, + 0xe3,0xa6,0xe2,0xe8,0xbb,0x83,0x2a,0xea,0xca,0x45,0x82,0x71,0xb3,0x3d,0x6c,0xba, + 0x44,0xa2,0x5b,0xde,0x9b,0x76,0x22,0xfa,0xcb,0x64,0xe0,0x9e,0xdb,0x5d,0x65,0x9d, + 0x29,0x8b,0xd6,0x6a,0x3b,0x81,0x6b,0xeb,0x24,0xc3,0xab,0xef,0xf8,0xde,0x02,0x2a, + 0xc0,0xae,0xf3,0xb5,0x5b,0xe0,0x63,0xfb,0x25,0x60,0xfd,0x54,0xef,0x69,0x64,0x82, + 0x39,0x1d,0xa4,0x6d,0xfb,0xef,0xb0,0xd2,0xc3,0xdb,0xac,0x21,0x7e,0xfa,0x6c,0x92, + 0x34,0x1c,0x4a,0x7c,0x41,0xaa,0x26,0x00,0xcf,0xfe,0xda,0x25,0x42,0x50,0x65,0x82, + 0xed,0x1d,0x5a,0xcd,0xb6,0x11,0xfd,0x9d,0x0b,0x16,0x52,0x56,0x99,0x73,0x6d,0x92, + 0xb0,0x1c,0x7e,0x6c,0x46,0x48,0xb9,0x41,0x1e,0x5c,0x25,0x4a,0xc2,0x72,0x24,0xc2, + 0x63,0x19,0x23,0x84,0x7a,0x76,0x50,0x06,0x83,0x4f,0x92,0x96,0x5c,0xfc,0x86,0x3a, + 0xc2,0x2e,0x0c,0xb1,0x1e,0x3f,0x24,0x4d,0x83,0xaa,0x64,0xa6,0x5d,0x16,0x4f,0xc9, + 0x01,0xbb,0x9d,0x12,0x32,0xd6,0x95,0x07,0x1f,0xfd,0xf5,0x1a,0xc1,0xe4,0x94,0x36, + 0x12,0xb6,0x4d,0x13,0xc3,0x31,0xee,0x13,0xe5,0x8e,0x97,0xb7,0xae,0x88,0x66,0x8a, + 0x35,0x15,0x82,0x60,0xb8,0x03,0x4c,0xd8,0x14,0x47,0x2e,0x52,0xf7,0x8e,0xd5,0x98, + 0x56,0x92,0x9e,0x18,0x61,0xbd,0x1c,0x84,0x9e,0x5d,0x31,0xbe,0x79,0x8d,0x67,0x8a, + 0xb1,0x15,0x71,0x71,0xb8,0xc1,0x2d,0x4f,0xb4,0xd1,0x9f,0xbc,0x25,0xa7,0x50,0x99, + 0x96,0x3b,0xef,0x9f,0x9c,0x36,0xb2,0x51,0x61,0xd0,0x81,0xbf,0xed,0xd6,0x7e,0x41, + 0x85,0xb1,0xe6,0xa4,0x9b,0xe3,0x73,0x6a,0x6b,0xbb,0xe8,0x88,0x12,0x71,0x15,0x3f, + 0x9a,0xbc,0xb1,0xa2,0xd0,0xdc,0x56,0x57,0x8a,0x52,0xe4,0x59,0x8c,0xf1,0x09,0x23, + 0x4b,0x25,0xa7,0xcf,0xd7,0x33,0x0d,0xe8,0x49,0x58,0x58,0x12,0x5e,0x6e,0x77,0x50, + 0x04,0x19,0xf0,0x2e,0x8b,0x3e,0xf7,0xd7,0x69,0x5c,0x0b,0x2d,0x5a,0x87,0x60,0x38, + 0xe5,0x9b,0xa2,0xe0,0x96,0xa4,0x88,0xc2,0x40,0x40,0x8a,0xce,0x7c,0xaf,0x56,0x4b, + 0x36,0xb5,0x50,0x94,0x95,0x2b,0x87,0x75,0x87,0x31,0xe1,0x3d,0xb0,0x3e,0x85,0xe5, + 0x94,0xcd,0xed,0x65,0xa7,0x69,0xc9,0x51,0x3b,0x1d,0xe8,0x29,0xb3,0xc2,0xd1,0xfb, + 0xb2,0x4c,0x91,0xff,0xe2,0x6c,0x71,0x0e,0xa6,0xd7,0x55,0xa8,0xd4,0x43,0xaa,0xaa, + 0x71,0xcb,0x54,0x24,0x25,0x60,0x08,0x24,0xba,0x88,0xa0,0x7f,0x35,0xc4,0x56,0x9a, + 0x4e,0x6f,0x17,0x25,0x2f,0xc9,0x42,0x9a,0x55,0x8a,0xed,0x90,0x64,0x27,0x5b,0xe6, + 0x94,0xc9,0x1b,0xaf,0x56,0x6b,0xb3,0xe7,0xd5,0xda,0x89,0x8f,0x9c,0x4b,0x71,0x5e, + 0x08,0x2a,0x0e,0x17,0xd5,0x0a,0x20,0x63,0x60,0xdc,0xc7,0x5b,0x70,0xa5,0x7b,0x0a, + 0xab,0x93,0xc2,0x0c,0x13,0xa5,0xa1,0xae,0x6e,0xc9,0x1d,0x50,0x81,0xec,0x4a,0x18, + 0x1c,0x84,0xf3,0x09,0xba,0xb2,0x10,0x07,0xa6,0x8d,0x45,0xd6,0x0d,0x14,0x36,0xfb, + 0x80,0xc5,0xfa,0xee,0x7b,0x27,0x69,0xd4,0x6f,0x41,0xb1,0xc7,0x8a,0xa7,0x4b,0x18, + 0xc8,0x84,0x32,0xe7,0x73,0xf0,0x01,0x8b,0x2f,0x64,0x43,0xbd,0x5d,0x32,0x2b,0xd8, + 0x0e,0x21,0x73,0xd1,0x1f,0x5c,0xd3,0x8c,0xcc,0xc8,0x3c,0xc4,0x58,0xe4,0xec,0xa7, + 0x03,0xcf,0xd4,0x77,0x90,0x5b,0x68,0x6b,0x7c,0xbf,0x3a,0xa7,0x38,0xf6,0xad,0xd9, + 0x82,0x86,0xba,0x59,0x7b,0x51,0xb9,0x09,0x8d,0x3e,0xf3,0xeb,0xac,0x61,0x26,0x5c, + 0x87,0x9c,0xa3,0x4e,0x76,0xfe,0x83,0x1d,0x30,0xd4,0xf8,0x19,0x24,0xaa,0xfd,0x81, + 0x1f,0x08,0xee,0x1b,0x07,0xb1,0xb4,0x44,0x57,0x3b,0xaa,0x61,0xb6,0x80,0x74,0xbc, + 0xa7,0x95,0x6b,0x7e,0x1d,0xfe,0x44,0x5a,0x62,0x9e,0x39,0x5e,0x55,0xbc,0xe5,0x03, + 0x54,0xd0,0x5d,0xa0,0x15,0x38,0x8d,0xb3,0x25,0x58,0xbd,0xa2,0x9f,0x5b,0x22,0xf1, + 0xab,0xf1,0x19,0xf5,0xf6,0x43,0x5d,0xb1,0xe6,0xde,0x42,0x86,0x9c,0x71,0x44,0x8b, + 0x87,0x4b,0xf7,0xdf,0x30,0xbf,0xf0,0x00,0xe4,0xd0,0x8a,0xaa,0x49,0xd4,0x13,0xac, + 0x14,0x0d,0xd4,0x25,0x0f,0xd0,0xfc,0x34,0x2f,0xd3,0x26,0x1e,0xef,0x38,0x05,0xc1, + 0xb7,0x9b,0x0b,0x45,0x36,0x1f,0x2a,0x81,0xc4,0x1b,0x42,0x96,0xf0,0xaf,0x95,0xa8, + 0xb7,0xd8,0xd5,0x24,0x83,0x4c,0x5d,0x0a,0x46,0xb4,0x00,0x1f,0xa1,0xba,0x6c,0x37, + 0x22,0xde,0xff,0x85,0xdb,0xb5,0x7c,0x17,0x87,0xe2,0x90,0xdf,0xdf,0x7c,0x16,0x1f, + 0xab,0x4b,0x6d,0x78,0xbf,0xbd,0x40,0x73,0xe2,0x5f,0xaa,0xd8,0x8a,0x04,0xe1,0x09, + 0x2c,0x91,0x8d,0x5f,0xe0,0xa1,0x21,0xc9,0x84,0xd7,0xee,0xa9,0x1b,0xe1,0x17,0x1e, + 0xa3,0xf9,0x37,0xfd,0x93,0xfd,0x37,0xfb,0xe1,0x70,0x2c,0x4c,0xb6,0xe0,0x06,0xc8, + 0x33,0x91,0xfc,0x32,0x3e,0xfe,0x96,0xe3,0x4c,0xec,0xe6,0xf7,0x3a,0x53,0x56,0x21, + 0xda,0x86,0x01,0xad,0x53,0xf2,0x46,0x08,0x90,0xdb,0xfc,0x0d,0x6a,0x48,0x9c,0x49, + 0x2e,0xc6,0x7c,0x71,0xb8,0xbd,0xbe,0x69,0x6e,0x2f,0x7e,0x9d,0x05,0xfa,0x27,0x3d, + 0x56,0x8f,0xee,0xac,0x8f,0xf0,0x5f,0xc7,0x4e,0x26,0xe1,0xc0,0x96,0xbd,0x99,0x8c, + 0x82,0x03,0x6f,0xea,0x90,0xb8,0x70,0x96,0x15,0x4d,0x7f,0xcf,0xd0,0xfc,0xc8,0xf0, + 0x1e,0x02,0xa8,0x42,0x91,0xaf,0x45,0xad,0xee,0xcc,0x9c,0x28,0x04,0x68,0x85,0xf1, + 0x88,0x0d,0xa1,0xc3,0x10,0x7d,0xbd,0xc9,0x00,0x84,0xb0,0xc7,0x2d,0x6b,0x0c,0xe8, + 0x03,0x07,0xa9,0x7c,0x11,0x6c,0xe6,0xb5,0xea,0xa0,0x35,0x3f,0x72,0xde,0x7a,0x1e, + 0xf9,0x45,0xbf,0x2f,0xce,0x2b,0x81,0x93,0xce,0x49,0x6b,0xc1,0xa5,0xd9,0xf3,0x42, + 0x23,0x4b,0xb0,0xae,0xae,0xf1,0xc8,0xb0,0x5b,0x78,0xa3,0x1b,0x7d,0x1a,0x7e,0xab, + 0x69,0x09,0xf3,0x7d,0x4b,0x85,0x2f,0x83,0x6e,0x4b,0x05,0x9e,0x23,0x05,0x0a,0xaf, + 0x7b,0x08,0xb1,0x67,0x64,0x12,0x4f,0x77,0x70,0x83,0x99,0xa2,0xdf,0x51,0x59,0x6a, + 0xc9,0x6a,0xa2,0xa9,0x98,0x2a,0x28,0xc0,0x37,0x87,0x80,0x28,0xba,0xe8,0xcc,0xfe, + 0x3a,0xed,0xaa,0x92,0x99,0x3c,0xe0,0xd0,0x22,0x86,0x3a,0x53,0x39,0x29,0xc7,0xd9, + 0x84,0x11,0xa3,0x3b,0x18,0x77,0x4a,0xc1,0x2f,0x5a,0x93,0xed,0x62,0xc5,0xb1,0xde, + 0x4b,0x2b,0xab,0xd3,0x19,0x66,0x1a,0xcf,0xfa,0xf0,0xe9,0x2d,0xd9,0x61,0x1c,0xaa, + 0x1a,0xf1,0xba,0x23,0xc6,0x23,0x2a,0x60,0xaf,0x0d,0xda,0x7c,0xe7,0x5a,0x35,0x18, + 0x47,0x1b,0x59,0x07,0x21,0xf2,0x4c,0x7e,0xf8,0x00,0xe0,0x97,0xec,0x2c,0xd4,0xb6, + 0x73,0x6d,0xf1,0x12,0x53,0x21,0xa6,0x97,0xde,0x73,0x2e,0x70,0x49,0xc3,0x03,0x4d, + 0x40,0x00,0xf1,0xe5,0x68,0x72,0x25,0x9b,0xdb,0x02,0x82,0xf5,0x26,0x9e,0x24,0x79, + 0x81,0x9a,0xb9,0x5a,0xdd,0x34,0xfb,0x4e,0xe0,0x83,0xae,0x23,0x54,0x8d,0xb8,0xf2, + 0xde,0x9d,0x28,0xe6,0xbf,0x54,0xa2,0xb9,0xc2,0x34,0xe4,0xeb,0xa1,0x7e,0x82,0x69, + 0x90,0x5d,0x82,0x8e,0x34,0x66,0x34,0xa7,0x30,0x36,0xb2,0x47,0x10,0x67,0x47,0x8c, + 0x92,0x71,0x77,0x9d,0x6e,0x0c,0xf2,0x5f,0x61,0x10,0xaf,0x9d,0x24,0xc7,0xe8,0x5f, + 0xdd,0x99,0x64,0x4b,0xcb,0x62,0xe0,0x02,0x46,0x5e,0x2d,0x96,0xa3,0x0b,0x22,0x97, + 0xc2,0xa3,0xad,0x94,0x63,0x9a,0x75,0x06,0x73,0x90,0x63,0xc9,0x8c,0xa8,0xa6,0x3f, + 0xa4,0xa6,0xfe,0x4e,0x5b,0x72,0x50,0x8a,0x8a,0x12,0x45,0x14,0x51,0x74,0x32,0xa3, + 0x71,0x88,0x6d,0xab,0x2d,0xe8,0x25,0xd5,0x5d,0x88,0x09,0x0b,0x0a,0x14,0xfe,0xee, + 0xa5,0x9e,0xbd,0x62,0x80,0x37,0xaa,0xa1,0x8f,0x48,0xee,0x9e,0x0c,0xa7,0x08,0x7e, + 0xab,0x1d,0x2e,0x92,0xb5,0xa4,0xa2,0xb1,0xce,0x49,0x6d,0xbc,0x41,0x84,0x01,0x49, + 0xa4,0x91,0xb8,0x62,0x9c,0x0e,0xf8,0x47,0x68,0x41,0x07,0x17,0xf8,0x0a,0xd4,0xfb, + 0xea,0xeb,0x76,0xff,0x15,0x27,0xf0,0x57,0x69,0x50,0xb8,0x5f,0x39,0x84,0x66,0xcd, + 0x2c,0xac,0xf9,0x42,0xc1,0xa1,0x53,0x83,0x02,0x18,0xa9,0xb6,0x54,0xe0,0xe2,0xaa, + 0xf5,0xe2,0xb6,0x0a,0xda,0xe1,0x5f,0x1e,0x4f,0x40,0x30,0xe9,0xe5,0xe0,0x29,0x69, + 0x61,0xfe,0xa2,0x37,0xe6,0x90,0x7e,0x0f,0x03,0x51,0xfe,0x48,0x6b,0x7c,0x75,0x47, + 0x5c,0x5e,0x32,0xaf,0x62,0x60,0xf8,0x1b,0x0b,0xc3,0x3e,0x97,0x61,0x77,0x28,0x17, + 0x37,0x62,0x80,0x48,0x94,0xc3,0xca,0x64,0x5e,0x8c,0x07,0x03,0x78,0x48,0xd0,0x90, + 0x85,0x1a,0x93,0xf8,0xf4,0xc7,0x8f,0xb6,0x6e,0x28,0xba,0xd3,0xeb,0xc1,0x99,0xfc, + 0x21,0x73,0x84,0x01,0x00,0xc6,0xf4,0x65,0xc0,0x8c,0x11,0x02,0x56,0x52,0x11,0xc3, + 0xfb,0x98,0x1d,0x5d,0x5c,0xe7,0x60,0x2f,0x30,0x8c,0x3b,0x3c,0x51,0xb7,0x98,0x66, + 0x8b,0x92,0xd2,0x7f,0xc3,0x07,0xe0,0x11,0xca,0x95,0x0f,0x18,0x78,0x3b,0xd1,0x76, + 0x82,0x2b,0x93,0x72,0x7c,0xaa,0x06,0x90,0xeb,0xf8,0x2c,0x8c,0xce,0x86,0x1e,0x5e, + 0x4d,0x89,0x99,0xbc,0x77,0x35,0x0f,0x64,0x7f,0xa0,0xce,0xc2,0x2d,0x7b,0x52,0xf3, + 0x6a,0xb7,0xe8,0xa6,0x13,0xa7,0x9d,0x57,0x74,0xb0,0xd4,0xf7,0x18,0x47,0xb7,0xec, + 0xa9,0x23,0x8b,0x54,0xd5,0xcc,0x33,0x55,0xeb,0x89,0x16,0x4c,0x78,0xe2,0x52,0x0b, + 0xcd,0x8f,0x84,0x18,0x8c,0x35,0xd5,0xd4,0xcd,0x01,0x41,0x3a,0xf0,0xa8,0x5b,0x0e, + 0x6c,0x21,0x88,0xed,0x30,0xb6,0x8d,0x22,0x2b,0xda,0x33,0x58,0xf8,0x9d,0xd9,0xdb, + 0x2e,0x8d,0x85,0x18,0x4c,0x55,0x85,0x32,0x6a,0xdb,0x9e,0x39,0x49,0x8f,0x92,0x99, + 0xef,0xe0,0x5d,0x73,0xe1,0x71,0x76,0xeb,0xa7,0x88,0x17,0x05,0xc8,0xe4,0x11,0x24, + 0x2d,0x60,0xc5,0x04,0x31,0x31,0xde,0xd6,0xa4,0xa9,0xc7,0xf0,0xe4,0x1d,0x04,0xb0, + 0x6f,0x18,0x37,0xb1,0x47,0xcd,0x66,0x98,0x4a,0x63,0x75,0x15,0x40,0x71,0x2d,0xfd, + 0x44,0x02,0xc5,0x59,0xb1,0x03,0x42,0x99,0x26,0xc0,0x92,0x1d,0x3e,0xd3,0x32,0xe0, + 0x4c,0x9d,0x8a,0x80,0xa5,0x2c,0x15,0xa4,0xb4,0xb4,0x83,0x44,0x50,0x7d,0x14,0x7a, + 0x33,0xde,0x18,0xdc,0xfc,0xf5,0xd3,0x5c,0xe5,0x58,0xbd,0xc9,0x09,0x0e,0x7c,0xaf, + 0x03,0xf7,0x8b,0x80,0x65,0xbd,0x89,0xaa,0x47,0xb7,0x9e,0x4d,0x9f,0xfd,0xed,0xff, + 0x26,0xd1,0x84,0xcd,0x7c,0xd7,0x18,0xb5,0x71,0xb7,0x06,0x12,0x02,0x6e,0x4a,0x20, + 0x95,0xf1,0xde,0x9c,0x8d,0xa1,0xd1,0x00,0x86,0x45,0x75,0x9d,0xe8,0x4b,0x14,0x38, + 0xce,0xd1,0xc0,0x7d,0x37,0x8f,0x4e,0xca,0x94,0x81,0x99,0x1c,0x2b,0x5b,0x5d,0xeb, + 0x05,0x3a,0x45,0xe3,0x04,0xb6,0x0e,0x88,0x32,0xd9,0xce,0x69,0x05,0xeb,0x2b,0xd5, + 0x84,0xd7,0x1c,0xd7,0xcf,0x2a,0x05,0x88,0x07,0x46,0x85,0x39,0x16,0x4b,0xe4,0xa7, + 0x2a,0xb3,0x8d,0x51,0x89,0x66,0x0e,0x8d,0x8b,0xc8,0x62,0x54,0x89,0x4e,0x77,0x07, + 0x4e,0x66,0x0e,0x90,0xb1,0x34,0x1b,0xbc,0xf9,0xbd,0xc5,0xc0,0xa7,0x26,0xa8,0x0f, + 0xef,0xa6,0x9e,0x8d,0x23,0x8e,0xd8,0x45,0x6c,0xc0,0x8c,0x25,0xfd,0x5a,0xd7,0x3b, + 0xe5,0xeb,0x4b,0xb8,0x1a,0xab,0x07,0x9c,0x4a,0xcb,0x38,0x6c,0x5e,0xc6,0x20,0xcd, + 0x8f,0x8f,0x43,0x2c,0xfe,0x40,0x0d,0x84,0xba,0xd3,0x0b,0x9c,0xaf,0xa3,0x2e,0xa9, + 0xab,0xac,0x96,0x91,0x84,0xa6,0xdb,0x18,0x8f,0x6c,0x43,0x61,0x94,0xf2,0x1f,0xef, + 0x10,0xbe,0x4c,0x94,0x4d,0x13,0x45,0xb0,0x5e,0xd1,0xcd,0xa5,0x45,0xbf,0x11,0xdd, + 0x46,0xfb,0xae,0xa0,0xc3,0x40,0x54,0x53,0x87,0xd0,0x46,0x61,0xfa,0xf0,0x3d,0x9b, + 0x05,0x0f,0x27,0xa0,0xe4,0xa3,0xb2,0xa4,0x42,0x84,0x90,0x64,0x54,0x48,0x98,0x7a, + 0x20,0xf1,0xa7,0xec,0x11,0x63,0xac,0x63,0xcd,0xed,0x8e,0x56,0x7e,0x40,0x38,0x9b, + 0xc9,0x0d,0x36,0xb4,0x49,0x5f,0x2b,0xc4,0x21,0x24,0xea,0xa7,0xda,0x16,0x32,0x56, + 0x8f,0x9c,0x0a,0x39,0x49,0x00,0x61,0x62,0x4d,0x5f,0x7c,0x14,0x2f,0x42,0x4c,0xba, + 0xeb,0xa7,0xda,0x45,0x31,0x64,0xfc,0xff,0x41,0xd6,0x10,0xe1,0x84,0x91,0x76,0xe0, + 0xc1,0x05,0x8b,0x14,0x4f,0x3e,0x66,0xd4,0xce,0xb3,0xc3,0x0f,0xd3,0xd5,0x27,0x95, + 0x69,0xe5,0xdd,0xce,0x94,0xac,0x6f,0xb0,0x80,0xb9,0x87,0x5b,0xb0,0x24,0x37,0xe5, + 0x8a,0x98,0x90,0x33,0x6c,0x8a,0x11,0xf5,0xc5,0xcd,0xe7,0xd5,0x5c,0xc1,0x3d,0x8d, + 0xf3,0xd5,0xd2,0x85,0x0e,0x33,0x3c,0x2e,0xd9,0x47,0xaf,0x6d,0x5e,0x40,0xf5,0xd2, + 0xa2,0x48,0x0a,0xdc,0x1f,0x92,0x62,0x6b,0xc5,0x55,0x2a,0x7d,0xc8,0x2b,0xc7,0xf7, + 0x75,0x68,0x5c,0x7b,0x15,0xac,0xa7,0x7a,0x44,0xe6,0xc5,0x6c,0xff,0x42,0x32,0x79, + 0xd5,0xf6,0x09,0x99,0xda,0xf8,0x35,0x3f,0x58,0x0a,0xd1,0x3d,0x30,0xc1,0x44,0x75, + 0xe3,0xc6,0x92,0x8b,0xc4,0x24,0xd5,0x2f,0xa3,0xef,0x41,0x2c,0x1e,0x2e,0x18,0xa7, + 0xfc,0x4f,0xd6,0xb1,0xf2,0x2e,0x64,0xc8,0x89,0x4d,0x39,0x6d,0x27,0x4c,0x51,0xb6, + 0x75,0x83,0x47,0x3e,0xb8,0x61,0x35,0xbd,0x21,0x7d,0x1f,0x1e,0xdc,0x0c,0x01,0x49, + 0x62,0x2c,0x27,0xce,0xef,0x27,0x25,0xd1,0xe2,0x8c,0xc4,0x59,0xb8,0x4f,0xb0,0xe2, + 0xd7,0x75,0x84,0x00,0x68,0x5c,0xff,0x4e,0x44,0x64,0x5e,0x94,0x8f,0x8f,0xe8,0x6a, + 0x42,0x31,0x1d,0x8b,0x49,0x2a,0x19,0x6f,0x92,0x64,0x50,0x53,0x77,0xfb,0x3d,0x7e, + 0x84,0x9f,0xda,0x8d,0xb6,0xe2,0x6d,0x61,0xac,0xbd,0xaf,0x15,0x0f,0x30,0xe9,0x6a, + 0xc2,0x53,0x2b,0xf3,0x3e,0xb5,0x65,0x95,0x5f,0x8c,0xd1,0xf2,0x2f,0x79,0x0e,0x5d, + 0xdd,0x78,0x53,0x34,0x02,0x95,0x43,0x13,0x58,0xc9,0x46,0xe1,0x50,0x15,0x5f,0x54, + 0x60,0x15,0x7e,0x65,0x01,0x9a,0x06,0x0e,0x0b,0xf6,0x70,0x1c,0xd9,0x38,0x7b,0xf9, + 0x7c,0xb9,0x90,0x36,0x36,0xbd,0x75,0x41,0xaa,0xa7,0x56,0x96,0xce,0xc9,0x73,0x70, + 0x2c,0x91,0x69,0xb7,0x44,0x9a,0x23,0x40,0x80,0xa8,0xba,0x13,0xe1,0x3a,0xe2,0x76, + 0x4b,0x78,0x86,0x4c,0x20,0x23,0x6d,0x4f,0x70,0xa6,0x54,0xdf,0x3f,0xf9,0xf4,0x90, + 0xd0,0xd6,0xc6,0x03,0x38,0xf9,0x20,0x74,0xe6,0xdf,0x32,0x23,0x78,0x39,0xe3,0x76, + 0x8c,0x87,0x5d,0xeb,0x47,0x97,0x6c,0x82,0x4b,0x1b,0x6c,0x52,0x11,0x59,0x0e,0xe7, + 0x4e,0x0b,0xb1,0xa4,0x34,0x59,0x1f,0x79,0xed,0x72,0x93,0x47,0xff,0xf1,0x46,0x88, + 0x70,0xb1,0x12,0x0b,0xe4,0x34,0x00,0x58,0x81,0xdf,0xb4,0xec,0xdd,0x67,0x9e,0x43, + 0x28,0x9f,0x2d,0x9c,0x4d,0xe0,0x5e,0x38,0x6f,0x74,0x60,0x7c,0x59,0xbc,0x09,0x59, + 0x51,0xb3,0xcd,0xbe,0x94,0x50,0x69,0x48,0x65,0xd8,0xa7,0x8b,0xea,0x7d,0x8f,0x09, + 0xb2,0xbc,0x0b,0x23,0x46,0x53,0x3a,0x8a,0xcd,0x31,0x5f,0x3b,0x93,0x31,0x8c,0xa7, + 0xfb,0x5d,0xff,0x0e,0x12,0x70,0x02,0x13,0xc0,0x6f,0xf2,0xdd,0xbd,0xa3,0x57,0x68, + 0x2b,0x1e,0xa8,0xef,0x19,0xa5,0x9c,0xc1,0xc9,0x80,0x86,0xe7,0x35,0x3e,0xf5,0xfd, + 0x7d,0xe1,0x30,0x18,0xe4,0x39,0x91,0x50,0x67,0x61,0x1d,0xbc,0xd7,0x40,0x40,0xf0, + 0xa1,0x4e,0x2e,0xee,0xd9,0xe1,0x86,0x6f,0xe4,0x81,0xc6,0x44,0xf3,0x8f,0x8c,0xd0, + 0x06,0x8c,0xb9,0x35,0x78,0x2b,0x76,0x5f,0xaf,0x0e,0x88,0x59,0x3c,0x31,0x0a,0x53, + 0x04,0xc5,0x92,0x36,0x0f,0xe7,0x40,0x8d,0xb6,0x87,0x68,0x04,0xbc,0x94,0xe2,0x30, + 0xac,0xe8,0xb9,0x42,0x7f,0x65,0x0e,0x9b,0xc6,0x67,0xa3,0xe3,0xff,0x1c,0x65,0xa9, + 0x81,0x0d,0xa3,0x6a,0x7e,0xa4,0xb5,0x95,0x2e,0x84,0x06,0x9f,0xa0,0x2a,0x59,0x02, + 0xe9,0x37,0xe8,0xb2,0x44,0xea,0x8d,0x4a,0x44,0x18,0xd5,0x6e,0x58,0xc0,0x90,0xe5, + 0x29,0x84,0xf1,0x1e,0x66,0x09,0x1f,0x3c,0xd9,0xad,0xc4,0x8b,0xa8,0xed,0x22,0x7d, + 0x7b,0x9a,0x20,0x23,0x40,0x3b,0x0c,0x84,0xc4,0xba,0xc8,0x5c,0xb6,0x1b,0x50,0x3c, + 0x2c,0x34,0x04,0x70,0x40,0x70,0x43,0x1c,0x12,0x54,0xa9,0x2e,0xa1,0x46,0xe5,0x0b, + 0xfd,0x2c,0x0e,0xd1,0x1f,0x05,0x9e,0xf8,0x4e,0xc4,0x09,0x29,0x50,0x43,0xae,0xa9, + 0x7b,0x20,0xd4,0x3c,0x7e,0x8d,0x9d,0xba,0x53,0x8f,0xe2,0x6f,0x34,0x9c,0xf4,0x38, + 0xfe,0xe2,0xff,0xc8,0x98,0xc4,0x37,0xef,0x8d,0xe4,0xe0,0x87,0x4a,0xa3,0x78,0xde, + 0x81,0xed,0xf3,0x92,0x99,0x25,0x31,0x66,0x26,0x6c,0xff,0x82,0xdb,0xec,0x9b,0x74, + 0x00,0x0d,0xda,0xbf,0xdd,0x21,0x53,0x26,0x19,0xf1,0xb9,0x17,0x16,0x5f,0x98,0xec, + 0x86,0xf4,0xd2,0xaa,0xd4,0x1e,0x66,0x9a,0x19,0x7e,0x2b,0xc5,0x32,0x70,0x5d,0xa4, + 0x5d,0x9d,0x61,0x02,0xf7,0x41,0x96,0x13,0x38,0x71,0x67,0xe6,0x07,0x52,0x92,0x71, + 0x81,0x86,0x3a,0xe4,0xc9,0xdf,0x9d,0x43,0x01,0x00,0xb9,0x48,0x14,0xb1,0x36,0x31, + 0x40,0xf8,0x20,0xfa,0xdd,0xb7,0x16,0xe2,0x65,0x94,0x66,0x0e,0xd4,0x7f,0x39,0xa1, + 0x45,0x43,0xbc,0x52,0x74,0x27,0x71,0x43,0x05,0x7a,0xef,0x10,0x57,0xe4,0x5b,0x72, + 0x78,0x39,0x09,0x54,0xce,0xbe,0x69,0x68,0xe0,0x5c,0xf1,0x01,0xe6,0x7d,0x13,0x7b, + 0x8e,0x54,0xe5,0x4b,0x84,0xac,0xaf,0x0f,0xe7,0x7a,0x37,0x1f,0xa2,0xba,0x86,0x99, + 0xa0,0x97,0xc4,0x86,0x3d,0xf8,0x48,0xad,0xcd,0x77,0x7a,0x48,0x95,0xbb,0xee,0x1a, + 0xe9,0xdb,0xd0,0x2a,0xd6,0x5a,0xe7,0xba,0x96,0x42,0x78,0xcd,0x5b,0x97,0x4f,0x8c, + 0x2f,0xde,0xa3,0x45,0xdf,0x45,0xe3,0xd8,0xab,0xa5,0x5b,0x3d,0xfc,0xf2,0x6f,0x8d, + 0xab,0x99,0x91,0xa2,0x5f,0xab,0x3f,0x3f,0xb9,0x8a,0xdd,0xbe,0xfe,0xbb,0x60,0xf7, + 0x4d,0xdc,0x5e,0x31,0xd7,0xbf,0x20,0xdb,0x29,0x73,0x0d,0x1f,0xdd,0x5c,0x54,0x6b, + 0x4d,0x32,0xd0,0x7e,0x98,0x1d,0x00,0x52,0xef,0x8e,0xa7,0x2e,0xda,0x62,0x71,0x7a, + 0x45,0x3d,0x0b,0x50,0xbf,0xde,0x22,0x95,0x84,0x5d,0xc5,0xdf,0xb6,0x41,0x3d,0x5f, + 0xec,0xb5,0xa7,0x5b,0xb0,0x12,0xbf,0x3e,0x06,0xd2,0x13,0x64,0xfe,0x6f,0x59,0xb7, + 0xa5,0x6e,0x6b,0x44,0x1c,0x21,0xa8,0xde,0x50,0x0d,0xc9,0xd8,0xb5,0x9f,0x52,0x11, + 0x81,0xc3,0xab,0x62,0xdb,0x50,0x9e,0x77,0xa0,0xb7,0x58,0x88,0x4f,0x6b,0x63,0x00, + 0x83,0x43,0x17,0xd0,0x1d,0x39,0xee,0x5f,0xe2,0xaf,0xee,0xdd,0xd0,0x0c,0x32,0xe0, + 0x22,0xa3,0x73,0xf5,0x95,0x6d,0xe6,0x43,0x17,0x9c,0x9f,0xb1,0xab,0xbd,0xfa,0xa0, + 0x42,0x14,0x99,0xdd,0xb7,0xdb,0x28,0xe2,0x60,0x74,0x90,0xfc,0xd1,0x69,0x93,0x26, + 0x8e,0x47,0xea,0xa7,0x31,0x88,0xf0,0x60,0xa2,0x5e,0x65,0x29,0xac,0x38,0x9b,0x45, + 0xa6,0x1d,0xff,0x91,0x4e,0x29,0x69,0x89,0x4e,0x89,0xac,0xa7,0x73,0x79,0x9a,0xd8, + 0x80,0xc5,0x03,0x4a,0x30,0xa3,0x4f,0x97,0xe1,0xf7,0x52,0x8b,0x6a,0xdf,0x30,0x38, + 0x40,0xb7,0x13,0xac,0x2c,0x21,0xbe,0x57,0x82,0xb0,0xda,0x25,0x6b,0xfc,0x4f,0xf0, + 0xe7,0x44,0xfb,0x7a,0xea,0x39,0x5e,0xf8,0x09,0x9c,0xfc,0x11,0xbe,0x72,0xb8,0xce, + 0x52,0x02,0x43,0xb4,0x77,0x31,0x2d,0x75,0xce,0x99,0x29,0x4d,0x98,0x06,0x11,0x18, + 0xa8,0x5b,0x33,0xe6,0x14,0xd6,0x90,0x06,0x94,0x50,0xb8,0x4b,0xfa,0x2b,0x82,0xf1, + 0xdd,0x06,0xfc,0xae,0x3b,0x6c,0x46,0xea,0x68,0xbc,0xad,0x06,0x0b,0xf3,0x5c,0x75, + 0xac,0x40,0xdc,0xfc,0x59,0x89,0xb8,0x91,0x2f,0x22,0x1a,0xfc,0x76,0xcd,0x07,0xa1, + 0x3c,0x43,0xc5,0xed,0x73,0xe4,0x6b,0x2e,0xf9,0x2a,0xbb,0x6b,0x59,0x0a,0xe7,0xcb, + 0xc3,0x07,0x9b,0xbf,0x5b,0x34,0x02,0x4d,0x6e,0xb0,0x8f,0x6c,0xa7,0x6b,0x5d,0x36, + 0x87,0x0b,0x97,0x00,0x46,0x20,0xc7,0x92,0x53,0x3c,0x54,0x1d,0xcb,0x1e,0x8d,0xd0, + 0x61,0x5f,0xf9,0xf2,0xfb,0xa0,0xa4,0x77,0xa3,0x01,0x99,0x30,0x07,0x79,0xf7,0xe7, + 0x2f,0x94,0xcd,0x05,0x3d,0x29,0xad,0x90,0xdc,0x1d,0x55,0x19,0xa4,0x7a,0x1c,0xe3, + 0x06,0x10,0x75,0x1d,0x14,0xb5,0x15,0x30,0x00,0x1c,0xc4,0xaf,0x96,0xb5,0xd2,0x26, + 0xaf,0x2f,0x3b,0xb7,0x18,0x5a,0xea,0x08,0xa2,0x92,0xd5,0x86,0xf0,0xe1,0xae,0x23, + 0x57,0x13,0x98,0xa6,0xd8,0xc4,0x64,0x0e,0x9e,0x81,0x9a,0x96,0x8c,0x73,0xe7,0xb6, + 0x91,0x92,0x22,0x85,0xb6,0xc2,0xaa,0x63,0xc0,0x46,0x8f,0x07,0xf4,0x5c,0xbf,0xc7, + 0xa5,0x3d,0xf3,0xe8,0x3e,0x91,0x25,0xe3,0x08,0x86,0x2f,0x78,0x52,0xa8,0x17,0x14, + 0x1b,0xdf,0x86,0x6a,0x0b,0xac,0x46,0x89,0x38,0x1a,0xb6,0x94,0xf7,0x85,0x57,0x74, + 0xcc,0x10,0x34,0x7c,0x23,0x15,0x47,0xa3,0x0e,0xd9,0xe7,0xc0,0xeb,0x71,0xbf,0xb8, + 0x94,0x55,0x5d,0x11,0x8b,0xae,0xc7,0x74,0xeb,0xba,0xf1,0x95,0x9b,0x7e,0x0d,0xeb, + 0x9a,0xdc,0x0b,0x19,0xc3,0xd4,0xb7,0x09,0xcd,0x58,0x9a,0x39,0x8f,0x73,0x5e,0xdb, + 0x89,0x1f,0x96,0x0c,0x6f,0x7e,0x36,0x5e,0x38,0x1e,0x69,0xd0,0xf8,0xe9,0xc9,0x3a, + 0xc2,0x1e,0xe6,0xda,0x9a,0x22,0x9b,0x8b,0xc8,0x52,0xfa,0xbc,0x18,0x4e,0x27,0x7a, + 0x36,0x95,0x8b,0xe8,0x3b,0x5a,0x1b,0x89,0x68,0x99,0x89,0x0f,0xde,0x78,0x57,0xcc, + 0x08,0x19,0x7b,0xbf,0x00,0x5a,0x9f,0x90,0x56,0x59,0xa7,0xda,0x98,0x5c,0x7a,0x06, + 0xa3,0x92,0xc7,0xf9,0xe1,0x36,0x43,0xa6,0x3e,0xdd,0x58,0x0a,0x76,0xb1,0x08,0x9b, + 0xe4,0x9a,0xa8,0xd1,0xe8,0x17,0x39,0x4d,0xe2,0xc2,0xe0,0xb2,0x66,0x8b,0x99,0x32, + 0xb8,0xcd,0x5a,0x3c,0xe4,0x39,0x79,0xa7,0x31,0x8d,0x29,0xcf,0xe3,0x2f,0xdf,0xf5, + 0x97,0xcc,0xf3,0x15,0x26,0x7a,0x2d,0x3f,0xc3,0x80,0x01,0xd7,0x8d,0xf8,0x65,0xaa, + 0xde,0x4f,0xa7,0xa0,0xf7,0x0b,0x20,0x15,0x5e,0x4b,0x45,0x77,0x22,0xc9,0x99,0xb4, + 0x23,0x9e,0xaf,0x30,0xe8,0x08,0xdc,0x84,0xc0,0x45,0x98,0x4c,0x74,0xea,0xe5,0x67, + 0x67,0x9d,0xb5,0xb4,0xe2,0xbd,0x73,0x85,0x67,0xdd,0x67,0x8f,0x16,0x2b,0x99,0xab, + 0x69,0x3c,0x7a,0x10,0x49,0xad,0x20,0x47,0x62,0xdc,0xa0,0x61,0x32,0x82,0x02,0x8b, + 0x3f,0x4f,0xc3,0x4e,0x08,0xb3,0xfd,0xea,0x04,0x8a,0xee,0x58,0xa3,0x84,0x22,0x0b, + 0xf8,0x7f,0xeb,0x78,0x6f,0xad,0x63,0x7d,0x2e,0xb9,0x69,0xa2,0x5c,0xa9,0x9b,0xf5, + 0x03,0x7c,0xd6,0x69,0xe4,0xe5,0xe0,0x19,0x4c,0xcb,0x8d,0x72,0x02,0xa8,0xd3,0x19, + 0xcd,0x06,0xe9,0x58,0x7c,0x0d,0xc3,0x39,0xed,0x89,0x9b,0x87,0xee,0xfc,0x66,0xa7, + 0x06,0xd7,0xb8,0xca,0x15,0xcd,0x64,0x8c,0xaf,0xca,0x8a,0x86,0x4a,0xa1,0x6a,0xa7, + 0x2f,0xcf,0xea,0x5e,0x1f,0xc1,0x3f,0x9c,0x49,0xc6,0xc1,0x59,0xfc,0x88,0x43,0xa2, + 0x60,0x55,0x23,0xcf,0xe3,0xae,0x05,0x21,0x6d,0xd5,0x88,0x67,0x7b,0x51,0x6c,0x49, + 0x6e,0x94,0xd5,0x8b,0x55,0xac,0xb6,0x3c,0xf4,0xab,0xc4,0x9d,0x5d,0xec,0xdc,0x6a, + 0xc2,0xdd,0xfd,0x98,0xd1,0xdc,0x26,0xa6,0xcc,0x5b,0xed,0xbc,0x13,0x22,0xaa,0xe0, + 0x82,0x8a,0xcb,0x66,0xb5,0xae,0x90,0xc1,0x38,0x27,0x7c,0x0f,0xce,0xea,0xc9,0x11, + 0xb4,0x9a,0x61,0x7c,0x39,0x4f,0x6c,0x42,0x01,0x2d,0x95,0x2f,0xc7,0xe5,0x0a,0x67, + 0xad,0xd2,0x36,0x1d,0xb6,0x33,0xfd,0x0f,0xb3,0xd9,0x66,0xc1,0x0e,0x9f,0x96,0xd4, + 0x87,0x14,0xdc,0x28,0x9a,0xb9,0x86,0x6b,0x9b,0xdb,0x8c,0xc1,0x34,0xfb,0x54,0x15, + 0xe5,0xc5,0xd1,0x94,0x96,0x38,0x04,0x70,0xe7,0x91,0xa6,0x76,0xd4,0x90,0x1d,0x41, + 0x40,0x52,0x18,0xad,0x37,0xbb,0x4f,0x61,0x00,0xfc,0xcf,0xc0,0x55,0x93,0x65,0xda, + 0xc4,0xc7,0x32,0xd6,0x40,0x08,0x45,0x1b,0xbd,0x98,0x85,0x1f,0xf7,0x6c,0x36,0xba, + 0x20,0x9b,0xff,0x94,0x5b,0x7e,0x2d,0x42,0xb8,0x15,0x8c,0x35,0x7a,0x2b,0xd0,0x72, + 0x1a,0x54,0x3f,0xd9,0x0e,0x2d,0xd2,0x3e,0x1b,0xeb,0x6d,0xfe,0x4e,0x6d,0x32,0xe2, + 0xaa,0xe2,0xb7,0xbf,0xb8,0x96,0xf3,0x2e,0xaf,0x29,0xb6,0x6f,0xb0,0xb8,0x77,0xda, + 0x9e,0xf0,0x15,0x0c,0x81,0x74,0x77,0xb3,0xeb,0x68,0x65,0xb3,0xce,0x6f,0x1e,0x48, + 0xc4,0xe8,0x9d,0x3e,0x98,0x1d,0xce,0x0a,0x6a,0x5c,0xd6,0x17,0x76,0x87,0x3e,0xd2, + 0x4c,0xbd,0xbc,0x69,0xd4,0xd9,0x92,0x68,0x33,0xd5,0x86,0x02,0x7f,0x06,0x3d,0xd6, + 0x0d,0x98,0xb3,0x3c,0x3a,0x33,0x8f,0x03,0xb4,0x93,0x08,0x03,0x8b,0xc5,0x17,0x59, + 0x8d,0x4f,0xd7,0x34,0x0c,0xfd,0xfb,0x0b,0xb3,0x90,0xef,0xfb,0xa7,0x7b,0x5e,0xa5, + 0xe4,0xab,0xb1,0x28,0x00,0x24,0xcf,0xf2,0x37,0xb6,0x93,0x65,0x50,0xc4,0x9e,0x63, + 0x6d,0x6d,0x4c,0x4a,0x1f,0x3f,0x90,0xdc,0x41,0xcc,0x48,0x75,0x51,0xec,0x53,0x29, + 0x61,0xad,0x03,0x5b,0x34,0xcf,0xd1,0x44,0xa0,0x39,0x06,0x84,0x18,0x61,0x6f,0xc0, + 0x80,0x43,0xf0,0xea,0x1c,0xa5,0x66,0xcc,0xc3,0x98,0xe7,0x94,0x3a,0x20,0x80,0xf0, + 0x21,0xb1,0x3f,0xac,0x65,0xe9,0x0b,0x42,0x39,0x64,0xb0,0x46,0x91,0x69,0x89,0x95, + 0xea,0xcf,0x08,0xe4,0x9b,0x2d,0x05,0xa2,0x45,0xf5,0x74,0x0b,0x89,0x9a,0x91,0x7b, + 0xa8,0x44,0x6d,0xc0,0x69,0x48,0x8c,0x60,0xf5,0xb0,0xaa,0x42,0x73,0xd9,0x17,0xb3, + 0x87,0x82,0x49,0x44,0xeb,0x87,0x7b,0x99,0xb4,0x8a,0x62,0xef,0x24,0xca,0x0e,0x95, + 0xe1,0xc2,0x8a,0x4c,0x1c,0xd3,0x22,0xac,0x71,0x12,0xec,0x04,0xb1,0x79,0x9f,0xe9, + 0x7b,0xb8,0x1b,0xe3,0x45,0x94,0x0b,0x7f,0x83,0x83,0x1c,0xb8,0x77,0x9e,0x7c,0xf1, + 0x88,0x71,0x54,0x7f,0x6f,0x81,0x29,0xda,0xf8,0xe7,0x3f,0xbe,0x9f,0x60,0xbc,0xa9, + 0x7d,0x68,0x89,0xee,0xa9,0x86,0x53,0x25,0xcf,0xc8,0x9d,0x15,0x59,0x24,0xf1,0xaa, + 0x62,0x8f,0x54,0x0d,0xa2,0x37,0xad,0x93,0xc7,0xe1,0x9c,0x5c,0xad,0xd3,0x9e,0xab, + 0x25,0xad,0x96,0x2a,0xa4,0x76,0x23,0x09,0x1e,0x5b,0x1a,0x60,0x6f,0xe0,0x3d,0xf9, + 0x7f,0xad,0x18,0x3b,0x65,0x35,0xdc,0xf2,0xa9,0x4a,0xe9,0xdd,0x25,0xf1,0xdd,0x58, + 0x93,0x09,0xcb,0x60,0x70,0xbe,0x13,0x71,0x36,0x23,0xa5,0x50,0x30,0xfe,0x5f,0x80, + 0x5b,0x18,0xba,0xac,0x72,0x9f,0xef,0x87,0xc1,0xaf,0xf2,0x04,0xf2,0x97,0x0e,0x63, + 0x19,0x9c,0x66,0xe6,0xda,0x12,0x22,0x11,0x17,0xfe,0xd4,0x14,0x77,0xf2,0xc5,0x9d, + 0x94,0xef,0x14,0x94,0x80,0x36,0x03,0x05,0x0b,0xc3,0x6c,0xc7,0x3a,0x83,0x73,0xbd, + 0x69,0x22,0xf3,0x31,0x5a,0x02,0x88,0xf6,0x08,0x10,0x91,0x5d,0x86,0xbe,0xfb,0x45, + 0xdd,0x12,0x7b,0xe9,0xcd,0xe9,0x6c,0x1b,0x9f,0x16,0x14,0x54,0xee,0xc2,0xf8,0xaf, + 0x80,0x98,0xac,0x67,0xff,0x38,0xf9,0x6b,0x92,0xdc,0xa2,0xdd,0x75,0xf6,0xb3,0x3b, + 0x57,0x19,0x14,0x3b,0x53,0x89,0x81,0xf3,0xe4,0xd5,0xab,0xc9,0x47,0xe0,0x2d,0x66, + 0x14,0x18,0xb4,0xf2,0x12,0x08,0x7d,0x1b,0x56,0xde,0x93,0x71,0xdd,0x23,0x17,0xfb, + 0x18,0x76,0xf8,0xa4,0xd1,0x29,0xf1,0x5b,0x1c,0xf5,0x3a,0x29,0x83,0x14,0x30,0xb0, + 0x27,0xb6,0xcd,0x18,0x5b,0xd8,0x4e,0xcf,0x21,0xd4,0xe7,0xc0,0xeb,0x73,0x65,0x89, + 0xa9,0x2a,0x2b,0x1e,0xff,0x30,0x43,0x37,0x03,0xeb,0x28,0x36,0x9b,0x7e,0x1e,0x88, + 0x9d,0x1f,0x70,0xda,0x73,0x6a,0x61,0x80,0x02,0x8a,0xd8,0xce,0x85,0x74,0xf2,0x2a, + 0x0e,0x69,0x72,0x48,0x58,0x48,0x76,0x62,0x69,0x1d,0xee,0x16,0xd6,0x71,0x1c,0xe6, + 0x05,0x5f,0x8e,0x34,0x34,0x70,0x0c,0xa1,0x6d,0x3e,0xe5,0x72,0xcc,0x11,0x15,0xe7, + 0x84,0xeb,0x07,0xd0,0x09,0x34,0x97,0x4c,0x6e,0x1c,0xa8,0xaa,0x64,0x01,0xd7,0xea, + 0x8f,0x92,0x97,0xd0,0x39,0x98,0xff,0x97,0x48,0x3a,0xe1,0xd1,0x25,0xd2,0xe0,0x67, + 0xac,0x0b,0xb1,0xc1,0xca,0xaa,0xa6,0x12,0x4e,0x82,0x87,0xf2,0x52,0x63,0x88,0x60, + 0x67,0xb7,0x7c,0xd9,0xee,0x2a,0x3e,0x1a,0xc5,0xbc,0x9e,0x92,0x77,0x4c,0x79,0x32, + 0xe8,0x2d,0xb3,0xf7,0x96,0xe0,0xe5,0xf8,0x84,0xcd,0xb2,0x34,0xfe,0x13,0x57,0x14, + 0x24,0x88,0x2e,0x93,0xbb,0xdd,0x95,0x41,0x0f,0x12,0x2e,0x97,0x38,0x93,0x96,0xa9, + 0xa7,0xea,0x59,0xe3,0xfd,0xd5,0xb4,0x93,0x3f,0xc4,0xae,0x53,0x5e,0x49,0x52,0xb0, + 0x85,0x62,0xed,0xbe,0x18,0xe8,0xee,0x01,0x2b,0xa9,0x6e,0x31,0x8d,0xef,0x03,0x09, + 0x87,0xd7,0xb8,0xab,0x73,0xad,0x0f,0x1f,0x27,0x69,0xbf,0xf7,0x2d,0x4b,0x12,0x31, + 0x70,0xe2,0xb1,0x47,0x12,0x44,0x1f,0xa2,0xc4,0xae,0xb2,0x86,0x74,0xa7,0xa2,0x2b, + 0x90,0xca,0xb5,0xf5,0x7f,0x8a,0x4c,0x8e,0xad,0x6e,0x1e,0x5c,0x96,0xeb,0x19,0x23, + 0x0b,0xdb,0xd4,0x37,0x92,0x7f,0xad,0x29,0x6b,0xca,0x2d,0xcd,0x21,0x85,0x71,0xeb, + 0x74,0x5b,0x63,0xaa,0x03,0x1b,0x24,0xd8,0xe6,0x65,0xcd,0x8f,0x3d,0x4c,0xe7,0x9f, + 0xef,0xa3,0xa3,0x0a,0x69,0x9a,0x5b,0x8c,0x3e,0xc6,0xdb,0x88,0x62,0xe6,0x5a,0xb5, + 0x8c,0x6b,0xc2,0x76,0x3e,0x4f,0x4c,0x5f,0x0e,0x33,0xcc,0x5b,0xbe,0x6d,0x0a,0xed, + 0xb8,0x80,0xf9,0xa6,0x1f,0x16,0x32,0xc7,0x49,0xae,0xc2,0x84,0xf3,0xe0,0x9e,0x29, + 0xf2,0x71,0xb1,0x71,0xa2,0x5b,0xcc,0x2c,0x04,0x64,0x1b,0xeb,0xf0,0xba,0xb8,0x1c, + 0x81,0x50,0xed,0xdb,0xc7,0xc3,0xdb,0x19,0x3c,0xaa,0x84,0xfb,0xf1,0xab,0x5c,0x06, + 0x0a,0x5d,0xac,0x9b,0xdd,0xe1,0x0a,0x8f,0x46,0x3d,0x00,0xd5,0x56,0xff,0x9f,0x37, + 0x23,0xf8,0x40,0x08,0x36,0x11,0x42,0x8a,0x8c,0x00,0x84,0x25,0x57,0xf7,0x7e,0x1c, + 0x58,0x11,0xb7,0x83,0x43,0x4f,0x33,0xd1,0x0f,0xa3,0x19,0x25,0x1a,0x4d,0xc2,0xe0, + 0xe2,0xec,0x6d,0x32,0x4b,0x13,0x8e,0x8a,0x55,0x82,0x4b,0x4d,0x54,0x55,0x1a,0xea, + 0xcd,0x25,0x42,0x42,0x34,0x4d,0xc9,0x00,0x0d,0xdb,0xe1,0x78,0x75,0xd5,0xa6,0xa0, + 0xcc,0x4d,0x7c,0x54,0xdd,0x51,0xda,0x81,0x5b,0xda,0x1f,0xb6,0x61,0xb7,0x75,0x5f, + 0xa2,0xb2,0xe5,0xc7,0xb6,0xb6,0xf5,0x9c,0xe0,0xb5,0x59,0x88,0x28,0xab,0x13,0x8e, + 0xd8,0x86,0x2d,0x57,0xca,0xb7,0xc9,0x80,0x97,0xd8,0x29,0xf1,0xf1,0x74,0xff,0x8a, + 0xd4,0xc9,0xb3,0x9f,0x0c,0xbc,0x37,0xa8,0x28,0x04,0x21,0x6e,0x30,0x55,0xee,0xeb, + 0x75,0xdb,0xcc,0x9e,0x3c,0x59,0xfa,0x70,0xde,0x66,0xee,0x5c,0xff,0x1e,0xf8,0x59, + 0xdb,0x6c,0xc8,0xfc,0x84,0xd4,0x87,0xdc,0xe2,0x06,0x20,0x4d,0x50,0x57,0xfb,0xed, + 0xde,0x6d,0x98,0xb6,0xbb,0x38,0x01,0x83,0x19,0xaa,0xc2,0xdd,0xbd,0xf4,0xbd,0xfc, + 0x28,0xcf,0xe6,0xce,0x3e,0x11,0x48,0xdf,0x4d,0x9c,0xf9,0x06,0x09,0x31,0x16,0xde, + 0xcf,0x62,0x2e,0x7b,0xab,0xb0,0x0c,0x7e,0x41,0x99,0xb6,0xe3,0x79,0x7e,0x9c,0xb8, + 0xe5,0x35,0xa9,0x4b,0xdc,0x87,0xd0,0xc3,0xb2,0xf6,0x5b,0x6b,0x9c,0x24,0xdc,0x39, + 0x9c,0x11,0x14,0xf8,0x1e,0x40,0x47,0x05,0x43,0xd2,0xb1,0x7b,0xd1,0xab,0xc0,0xb0, + 0x59,0x04,0x19,0x88,0x23,0xf2,0x24,0xde,0xa9,0xc9,0xb0,0x21,0x3b,0xa8,0xbc,0xd7, + 0xe8,0x90,0x32,0xfb,0x6d,0x9e,0x2c,0x49,0x72,0xd3,0x67,0x12,0x1d,0x06,0x03,0x10, + 0xec,0x2b,0x39,0xfa,0xa3,0x16,0x0b,0x20,0xe1,0x02,0x95,0x56,0xb1,0xe0,0x6f,0x6d, + 0x68,0x72,0xb3,0xb0,0x62,0x38,0xa1,0xd1,0xd3,0x58,0x79,0x08,0x75,0x33,0x9b,0xa8, + 0x4c,0x49,0xd0,0xc4,0xb3,0xa6,0xe8,0x24,0x7a,0x40,0xc0,0x21,0xaf,0x6b,0xe4,0xcf, + 0x00,0xc4,0xd9,0xd0,0x33,0x27,0x62,0x8f,0xc3,0x27,0x18,0x54,0x51,0xee,0xbe,0xa9, + 0xee,0x4b,0xb9,0xb5,0x35,0x87,0x90,0x90,0xfa,0x66,0x8b,0x83,0xba,0x77,0x10,0x46, + 0x66,0x81,0xf1,0x45,0x30,0x92,0x67,0x58,0x80,0x48,0xdd,0x97,0xb8,0x68,0x64,0x71, + 0x09,0x2a,0xa6,0x7a,0xaf,0x85,0x02,0x4e,0xb7,0x0a,0x72,0x8c,0x6b,0xa8,0xf5,0x6b, + 0x35,0xaa,0x75,0x22,0xba,0x6b,0xa5,0xde,0x7a,0x68,0x22,0xcf,0x4c,0x72,0x3d,0x31, + 0xe0,0xd3,0x9d,0x03,0x3b,0xaf,0xd4,0x5b,0xfb,0x2a,0x2b,0xde,0xc1,0x7a,0x14,0x5e, + 0x87,0xa4,0x8c,0x5a,0xaa,0xeb,0xa3,0xc6,0xcf,0xf2,0x9a,0x5b,0x32,0x13,0x46,0x08, + 0x0e,0x4b,0x54,0x73,0x2a,0x6e,0x4a,0x71,0xab,0xe3,0x52,0x1f,0x36,0x2e,0x1a,0xd9, + 0x43,0x09,0xca,0xd8,0x3b,0x45,0x4c,0x4d,0x4d,0x4c,0xcb,0xf8,0x7b,0xcb,0xc2,0xe9, + 0x9e,0xae,0x59,0x3d,0x9c,0x2f,0x46,0x96,0xa9,0xc2,0xc3,0x49,0x25,0xc3,0x4a,0xf9, + 0x81,0xaf,0x74,0xbf,0xf8,0xa3,0x56,0x0b,0x68,0xc4,0x85,0x9f,0xdf,0xc2,0xe7,0x04, + 0x72,0xfa,0x84,0x00,0x68,0x5c,0x4d,0xb8,0xc5,0xef,0xb2,0xb0,0xf7,0x32,0x42,0x50, + 0x39,0xe4,0xb7,0x28,0xc2,0x6c,0x16,0xb2,0x9e,0x4a,0x22,0xf3,0x42,0x95,0x3b,0xb4, + 0x2d,0xb4,0x3a,0xb4,0xf9,0x8d,0xa5,0x30,0x01,0x31,0x7d,0xa1,0xcb,0xd6,0x9b,0x15, + 0x8b,0x80,0x9b,0xf7,0x79,0x9a,0x5e,0xd7,0x20,0x30,0x7f,0xf5,0x8c,0x3f,0x2c,0xc6, + 0xa1,0x70,0x6b,0x40,0x5f,0xea,0x94,0xc0,0x32,0x59,0xc2,0xcc,0xc1,0x69,0x9c,0xa2, + 0xc8,0xf4,0x5a,0x50,0x68,0xb9,0x9c,0xd0,0x1b,0x58,0x85,0x30,0xd6,0xaa,0x2d,0x23, + 0x21,0x1b,0xea,0xae,0x6b,0xc3,0x0d,0xe5,0x4b,0xa8,0xfd,0x87,0x57,0x89,0x17,0x83, + 0xcb,0xf6,0x0d,0xf5,0xe3,0x3a,0x20,0x03,0xc0,0x17,0x62,0xa9,0x0c,0x79,0x00,0xbd, + 0xa8,0x17,0xfe,0xbe,0xc7,0x54,0xc2,0x78,0xe9,0xa0,0x17,0x44,0xb0,0xb3,0xf5,0xbf, + 0x88,0xe6,0xe8,0x7e,0xce,0x22,0x26,0xe5,0x96,0x1c,0xc3,0xbf,0x94,0x62,0xef,0x3c, + 0x8c,0x17,0xb8,0x12,0x47,0xa7,0xe8,0xda,0xcd,0xfb,0x97,0x45,0x70,0xba,0x50,0x4b, + 0xda,0x3e,0x4c,0xfb,0x85,0x84,0x1e,0xcb,0xc7,0x84,0x3f,0x2b,0xf8,0xa1,0x86,0xe8, + 0x33,0x11,0x39,0x3c,0xfb,0x0d,0x6a,0x8c,0x09,0xd5,0xee,0x06,0x87,0x33,0x82,0x28, + 0x8c,0x5f,0xb6,0x2c,0x5a,0x0c,0x4b,0x10,0xeb,0x10,0xe0,0xd4,0xf6,0xfb,0xab,0x5b, + 0xaa,0x16,0x07,0xed,0xa3,0xc3,0x42,0x03,0x4f,0xf1,0xf7,0xe4,0xb2,0x6f,0x5f,0xc5, + 0x0a,0x14,0xb6,0xae,0x83,0x70,0xa0,0x92,0x66,0xa9,0x58,0xbd,0x35,0xdf,0x3f,0x7d, + 0x0a,0x2f,0x1b,0xe0,0x04,0x5d,0x27,0xca,0x0c,0x3d,0xb1,0x40,0xbf,0x78,0xe8,0xb7, + 0xd3,0xc3,0xf0,0x06,0x26,0xa0,0x2c,0x54,0xba,0x83,0x84,0xb2,0x68,0x44,0xba,0x87, + 0xaa,0x5f,0x59,0xef,0xc6,0xef,0xc9,0x21,0x82,0xd9,0x86,0x73,0xd2,0x98,0x6a,0xc6, + 0x6c,0x62,0x89,0x13,0xa6,0x82,0xfe,0x41,0xf6,0x63,0x87,0x47,0x5a,0x45,0xa0,0xa3, + 0x71,0x80,0xf5,0xc2,0x36,0x9c,0x6a,0x53,0x2a,0xdb,0x66,0xe4,0xf6,0x9e,0xa8,0x86, + 0x4d,0x9e,0x6a,0xd2,0x37,0x14,0x68,0x97,0xba,0xca,0xc6,0x5e,0x51,0xe4,0xe5,0xc7, + 0xad,0xed,0xdb,0xa5,0xa5,0xfd,0x4f,0x4a,0x61,0x84,0x31,0x47,0xbe,0x19,0xff,0x35, + 0xc7,0xc8,0xb3,0xa8,0x34,0x8a,0x7f,0x46,0x2e,0x26,0x8d,0xf3,0xf7,0xe2,0x3a,0x03, + 0x46,0x69,0x1a,0xfd,0x55,0xb3,0x8d,0xcc,0x7f,0xc9,0xac,0xee,0x58,0xc4,0x79,0x18, + 0xa2,0xcb,0x55,0x6c,0x7f,0x56,0x2d,0xd2,0x41,0x34,0xe6,0x8b,0x36,0x60,0x94,0x3e, + 0x8a,0xa9,0x03,0x79,0xfc,0x55,0x8b,0xd4,0xca,0x73,0x60,0x5d,0x23,0xa8,0xff,0x65, + 0x8b,0xe8,0x50,0x24,0xf4,0x30,0xc3,0xbf,0xbf,0x44,0xbb,0x99,0xc9,0xf0,0x42,0x43, + 0x3d,0x6d,0x0d,0x5f,0x2e,0x80,0x68,0x77,0x6d,0xda,0xa8,0x87,0x58,0xed,0xaa,0x32, + 0xc9,0xcf,0x6d,0x3e,0x13,0xc7,0xec,0x3d,0x85,0x75,0x5f,0x4f,0x6f,0xf2,0x59,0xad, + 0x09,0xce,0x5a,0x3c,0xa6,0x24,0x49,0x98,0xa2,0x63,0x64,0x0d,0x21,0x65,0xe4,0x2f, + 0x0c,0x81,0xfe,0xbd,0x42,0x92,0x73,0x7f,0x66,0xa2,0x44,0x99,0xbc,0x66,0xe4,0xe7, + 0xfb,0x34,0x9e,0x23,0xc7,0xf2,0x1e,0x07,0x27,0xdd,0xed,0xa5,0x13,0xf0,0x14,0xd0, + 0x86,0x9d,0x17,0x70,0x25,0x4c,0x38,0x8d,0x0c,0x93,0xb9,0x66,0x4e,0xe5,0x34,0xb6, + 0x80,0x9e,0xa2,0xc0,0x87,0xa2,0xba,0x50,0xf1,0xa9,0xec,0xad,0xb0,0xf1,0x89,0xd1, + 0x21,0x9f,0x55,0xe4,0xd4,0x34,0xa4,0x47,0xd6,0xb3,0x03,0x5f,0x61,0x35,0xe9,0x32, + 0x47,0x35,0xd8,0x19,0x30,0xb5,0x7c,0x27,0x8f,0xe5,0x62,0xa5,0x98,0xb5,0x79,0x56, + 0x07,0xfe,0x36,0x52,0x17,0x25,0x02,0xda,0x54,0xd1,0xc2,0x87,0xa3,0xfa,0xf3,0x29, + 0x03,0x39,0xf2,0xa5,0x55,0xbd,0x3f,0x01,0xc5,0x6e,0xac,0xe4,0x13,0x29,0x55,0x2c, + 0x4e,0xa6,0xd5,0x10,0x84,0x9c,0xc5,0x0c,0x0e,0xc6,0x3d,0xaa,0x0e,0xff,0x4e,0x7b, + 0xaf,0x9a,0xa2,0x9f,0x57,0x70,0x8e,0x55,0x5f,0x78,0xbe,0xf6,0x4f,0x19,0xaa,0xd9, + 0x5b,0x82,0xb4,0xef,0x54,0xb2,0x84,0x55,0x5e,0x0b,0x3e,0x3a,0x00,0x22,0x37,0x83, + 0xec,0xd4,0xa7,0x8d,0xe8,0x17,0x8f,0x50,0xdf,0xee,0xed,0xae,0x5b,0xb6,0xb9,0xfd, + 0x8c,0xdb,0xa9,0x6e,0xf8,0xdb,0x87,0x48,0xf8,0x99,0x9f,0xff,0xfb,0x02,0x3e,0x46, + 0x1d,0x18,0x04,0x8e,0x4f,0x31,0xda,0x75,0x6f,0x9c,0x72,0xd1,0x17,0xbd,0xd6,0xba, + 0x23,0x60,0xe0,0xbc,0x1c,0xe7,0x70,0x98,0x4c,0x7e,0xfc,0x81,0xa9,0x02,0xdf,0x2b, + 0xaa,0x8c,0x99,0xe7,0xb8,0xbf,0x4b,0x34,0xe8,0xdf,0x48,0xa8,0x28,0xf6,0x77,0xce, + 0x9c,0xbb,0x2f,0xff,0xbf,0xfd,0x25,0x1d,0xd7,0x9d,0x6f,0x02,0xff,0xbe,0x37,0x28, + 0xfc,0xe1,0xb0,0x66,0xeb,0x62,0x49,0x0d,0xab,0x04,0x64,0xd7,0xdc,0x21,0x19,0x94, + 0x6c,0xdf,0xf0,0x26,0x35,0x8c,0xbc,0x14,0x22,0xa5,0xa2,0x84,0xff,0xce,0xc1,0xd8, + 0x41,0xf7,0xdd,0x00,0x6d,0x8d,0x2b,0x91,0x6e,0xed,0x83,0xe9,0x3b,0x26,0x53,0x76, + 0xe9,0xe2,0x1a,0x25,0x95,0xdc,0x8c,0xc2,0x45,0xce,0x3d,0x11,0xba,0x52,0x20,0x42, + 0x79,0x09,0xc8,0x55,0xf3,0x6b,0xa8,0x1e,0x29,0x4b,0x5e,0xec,0xaa,0xb5,0xdc,0x58, + 0x05,0x2e,0x17,0x50,0x15,0x0e,0xaa,0xfd,0xe2,0xb4,0xf8,0xe1,0xea,0xc4,0x51,0x32, + 0x8e,0x44,0x01,0x34,0x71,0x67,0xd6,0x53,0x3d,0x40,0xe2,0x5c,0xa5,0x46,0xc6,0xd5, + 0xea,0x88,0xa3,0xa8,0x97,0x65,0xa6,0xf5,0xf2,0x47,0xe1,0x9e,0x1b,0x16,0x7c,0x0e, + 0xe9,0x8b,0x42,0x75,0xe7,0xd5,0x40,0x8f,0xa3,0x2c,0x6d,0xae,0xbe,0x5a,0x21,0x63, + 0xd8,0x75,0xb0,0xac,0xb7,0x86,0x28,0x08,0x82,0xe6,0xc5,0xbd,0x5f,0x71,0xe4,0xfa, + 0x04,0x4b,0x2f,0x29,0x73,0x6e,0x83,0xd8,0x6b,0x8a,0xab,0xd2,0xe7,0x5b,0xb4,0x56, + 0x34,0xa0,0x2f,0x39,0x72,0x6f,0xbb,0x4b,0xab,0xcc,0x9b,0x22,0xe9,0x6d,0x78,0xa0, + 0x10,0x43,0x9e,0xea,0x3e,0x37,0xe9,0x9b,0x26,0x57,0x44,0x7f,0x2a,0x7d,0x3c,0x12, + 0xa8,0x16,0xaa,0xeb,0x22,0x20,0xa5,0x0b,0x27,0x23,0x1a,0x29,0x49,0xf8,0x63,0x58, + 0x6b,0x08,0x1a,0x3b,0xbb,0x1e,0xc2,0x0f,0xa2,0x7f,0x6a,0xe9,0x9f,0x0a,0xde,0x3f, + 0x74,0x14,0xd9,0x51,0x38,0x2b,0xbc,0x39,0xff,0x54,0x4c,0x46,0xf9,0xe2,0x84,0x00, + 0x80,0x1d,0xfa,0x82,0xd1,0xb3,0x6a,0xa6,0x81,0xd3,0x73,0x64,0x74,0x84,0x1d,0x63, + 0xa5,0x9c,0x1c,0x64,0xa5,0xc0,0x62,0xb7,0x0a,0x5e,0xe4,0xa4,0x91,0x8e,0xfa,0x71, + 0x61,0xb3,0xf7,0x76,0x3c,0x3f,0xe3,0x52,0x6c,0x13,0x80,0xd6,0xc8,0xd9,0x5f,0x23, + 0x4a,0x77,0xf3,0x93,0x50,0xb0,0x9d,0xc2,0xd9,0x11,0x71,0xc6,0xcd,0x85,0x45,0x42, + 0xc4,0x46,0x86,0xa4,0x62,0xb5,0x44,0x93,0x6e,0x16,0xd4,0xe6,0x68,0x89,0xb3,0xaf, + 0xac,0x93,0x17,0xd6,0x6b,0xce,0xd3,0x72,0x89,0x49,0xcf,0x07,0xf7,0xd8,0x7d,0x86, + 0x68,0x07,0x45,0x25,0xe2,0xcd,0xc1,0xe9,0xe4,0x7d,0x8b,0xe2,0xf2,0xd7,0xcd,0x91, + 0xbb,0xea,0x04,0xd7,0xab,0xcc,0x65,0x11,0xf9,0x4c,0x79,0x44,0xcf,0x35,0x96,0xe7, + 0x43,0x17,0xf4,0x7f,0xb4,0x35,0x56,0x8a,0xc9,0xc7,0xa8,0x80,0xb2,0x77,0x9e,0x68, + 0xb9,0xe8,0xf0,0x9a,0xd8,0xba,0x08,0xda,0x4d,0xa6,0x24,0x43,0x4a,0xbd,0x87,0x0b, + 0x08,0x60,0x17,0x7d,0x24,0xcb,0xa3,0xcb,0x13,0xa7,0x9f,0xed,0xcb,0xfe,0x71,0x9f, + 0x48,0x98,0xfd,0x6e,0x35,0x36,0x46,0xbe,0x4c,0x83,0x25,0x22,0x0e,0x60,0x24,0x36, + 0x29,0x9c,0x14,0xce,0x72,0x91,0x16,0x8e,0x49,0xde,0x58,0xf0,0x79,0xac,0x2e,0x6e, + 0x3d,0xb0,0xae,0x6b,0x02,0x30,0xc8,0x7a,0x8d,0x6f,0xcd,0x8e,0x11,0x0c,0x7d,0x21, + 0xa8,0x51,0x8a,0x8a,0xb4,0xc1,0x97,0x80,0x57,0xaa,0x68,0xdc,0x8a,0xd1,0x5e,0x3b, + 0xc0,0x10,0x63,0x4f,0x88,0x35,0x67,0x88,0x87,0x56,0xa1,0xd0,0x62,0xf7,0x58,0x06, + 0x86,0x85,0x9a,0xb6,0xba,0x0f,0x4e,0x25,0xb1,0xcf,0x42,0xbe,0xf5,0x1f,0x10,0xec, + 0xa9,0x8c,0xd6,0xf4,0xf5,0x10,0x40,0x49,0x2e,0xce,0xb8,0x29,0x65,0xe7,0x76,0x87, + 0x86,0x87,0x05,0x23,0x64,0xad,0x85,0x5c,0x67,0x83,0x8b,0xdc,0xd2,0xfa,0xb9,0xe3, + 0xdb,0x22,0x56,0x64,0x36,0x30,0xb9,0xb1,0x65,0xb9,0x4b,0xba,0x74,0xa1,0x25,0x24, + 0x46,0xcb,0xe6,0x34,0x94,0x43,0x30,0x04,0x65,0xa4,0x0b,0x19,0x2e,0x4b,0x64,0x19, + 0xe6,0xca,0x29,0xa6,0x5c,0xf4,0x38,0x14,0x07,0x8a,0x5c,0xb1,0xbe,0x74,0x8d,0xdc, + 0x85,0xc6,0xfc,0xa5,0xa1,0x56,0xc9,0x73,0x61,0xdd,0x51,0x15,0xa4,0x49,0xa9,0x8b, + 0x4f,0x53,0x90,0x31,0xb4,0xe7,0xd5,0xe1,0x87,0xcf,0x9f,0x71,0x3e,0x96,0xb4,0xf9, + 0x88,0x05,0x59,0x2a,0x67,0x88,0xa2,0xdb,0xef,0x08,0xfe,0x27,0xfd,0x47,0xba,0x65, + 0x66,0x86,0x75,0x03,0x19,0x19,0x9a,0x48,0x2f,0x6e,0x2f,0xd6,0x53,0xa4,0x71,0x29, + 0x67,0xee,0x7e,0x0e,0xeb,0xaa,0x01,0x1b,0xb0,0x65,0x22,0x08,0x7d,0x45,0xab,0x99, + 0x2d,0xab,0x89,0xef,0x05,0x5a,0xab,0xcb,0x42,0xfa,0x44,0x4c,0xe5,0x87,0xf3,0x55, + 0x32,0x28,0xc6,0x51,0xe2,0x96,0x33,0x18,0xe9,0x61,0x94,0x69,0x5f,0x1c,0x14,0x72, + 0xee,0x72,0xb2,0x73,0x2c,0xe9,0x85,0xfe,0x48,0x56,0xe9,0xed,0xdb,0x42,0xf6,0x62, + 0x67,0xdf,0x23,0x1b,0x01,0xa3,0x62,0x83,0x0e,0x0f,0x4c,0x9c,0x5a,0x43,0x32,0xdb, + 0x2a,0x86,0x53,0xcf,0xbe,0xdf,0x1b,0x79,0xb4,0xc2,0xe8,0x0c,0xe3,0x69,0x56,0x71, + 0xa8,0xd1,0x34,0x02,0x23,0x5d,0xcc,0xaa,0xc1,0x28,0xa2,0xc0,0x8f,0x9c,0x71,0x74, + 0x52,0x91,0x17,0x04,0x35,0xf0,0x04,0x48,0xc9,0xdc,0x82,0x9e,0xf8,0x57,0x7a,0x83, + 0x93,0x64,0x09,0xf8,0x76,0xba,0xcd,0x87,0x0f,0xb6,0x0e,0x3c,0x1f,0x13,0xf2,0x8e, + 0x9a,0xb3,0x82,0xe8,0x6c,0x2f,0x42,0x37,0x9c,0x6f,0x2b,0x77,0x85,0xf5,0xe3,0xd0, + 0xcd,0x75,0xe6,0x36,0x47,0x45,0xf2,0x91,0x0a,0xdb,0xf0,0xad,0x83,0x7d,0x97,0xa3, + 0x4b,0x9c,0xd4,0x25,0x4f,0xd0,0x25,0x1e,0x82,0xdc,0x76,0x39,0xd6,0xcd,0x05,0x75, + 0xf4,0x9b,0x1a,0x43,0xf3,0xa3,0x4f,0x0b,0xe2,0x99,0xf1,0x87,0x5a,0xb4,0x2f,0x51, + 0x41,0xa5,0xd5,0x24,0xc3,0xf5,0x78,0x1b,0x73,0x9a,0x85,0xe4,0xcb,0xc6,0xa6,0x0a, + 0xdc,0x13,0x1d,0xd4,0x18,0x13,0xda,0xd5,0xae,0xd8,0xc0,0xe4,0xdd,0x78,0x8e,0xe8, + 0x4f,0xfe,0x63,0xba,0x5d,0x2a,0x60,0x58,0x69,0xdf,0x2e,0xcd,0x4d,0x08,0x8b,0xba, + 0xc0,0x35,0xdf,0x8b,0x3e,0xbf,0x8c,0x39,0xe8,0x9b,0xcf,0x3d,0xf4,0xf2,0x51,0x9c, + 0x89,0x10,0xd1,0x99,0x5c,0x38,0x0f,0x02,0xe9,0xd9,0x40,0x3b,0xfa,0x60,0x5e,0xbb, + 0x42,0x95,0x6c,0x7d,0x9f,0x13,0x89,0x02,0x6a,0x91,0xd0,0xd6,0x4a,0xc1,0x6a,0x3c, + 0xc6,0x7c,0xbe,0xac,0x84,0xe0,0x36,0x98,0x90,0xc6,0x68,0xed,0x0b,0xec,0x64,0x23, + 0xac,0x15,0x70,0xe8,0x1f,0x11,0xe0,0x0d,0x6c,0x19,0xaf,0xf3,0x36,0x4f,0x17,0xa9, + 0x9c,0xdf,0x2f,0x8b,0xd8,0xfd,0xff,0x9d,0x62,0x29,0xd9,0xc2,0xc7,0x5b,0x50,0x2c, + 0x80,0xd1,0xd6,0x28,0x16,0xaa,0xbc,0xa5,0xff,0x02,0xae,0xf4,0x9a,0x0a,0x51,0x1a, + 0xa4,0x7e,0x75,0x67,0x5a,0xa3,0x64,0xc0,0xdd,0x10,0x40,0x73,0xb8,0x2b,0x3c,0x21, + 0x21,0x60,0x60,0xc5,0x94,0x07,0x8b,0xf3,0xc6,0x8a,0x7d,0xb7,0x90,0x68,0x3e,0xb1, + 0x71,0xf2,0x97,0x20,0xb0,0x01,0x60,0x4e,0x66,0x1e,0xff,0xf4,0x2e,0x0d,0xd5,0x20, + 0x06,0x20,0x99,0x4f,0xb7,0xdb,0x6e,0x4d,0x2a,0x49,0x40,0x16,0xb9,0x85,0xe6,0x41, + 0x6f,0x21,0x80,0xa0,0x5b,0x94,0x98,0x51,0x1f,0xc3,0xd7,0xb4,0x30,0xee,0xef,0x50, + 0xb6,0x22,0xff,0x1c,0x1d,0xd0,0x47,0x03,0x29,0x97,0xef,0x50,0x5f,0xc0,0x79,0x75, + 0x5f,0x76,0xe5,0x88,0xdb,0xb6,0x5f,0xb1,0x8f,0x05,0x65,0x44,0xbf,0x25,0xb5,0x24, + 0xfc,0x39,0xbc,0xd8,0x6b,0x28,0x0a,0x2c,0x61,0x59,0xf0,0x3c,0x59,0xa8,0x1f,0x07, + 0x3d,0x34,0xdc,0x30,0x1f,0xa3,0x43,0xd5,0xae,0x52,0x82,0x5d,0xd4,0xc4,0xc3,0x7d, + 0x4b,0xde,0x95,0x20,0x63,0xb7,0x83,0x5b,0x23,0x7b,0xad,0xfd,0xb1,0x00,0x1b,0x7a, + 0x87,0x10,0xef,0xdd,0x9d,0x0e,0xd7,0xdf,0x22,0xaa,0xd1,0xae,0xd6,0xeb,0xaa,0x70, + 0x69,0x85,0xee,0x10,0x38,0xbd,0x46,0x65,0x88,0xec,0xc2,0xec,0xfb,0x65,0x32,0x9f, + 0xc9,0x0f,0x35,0x2f,0x67,0xa2,0x38,0x3a,0xba,0xcb,0x4c,0xf8,0x7b,0x4e,0xd4,0xa3, + 0x2f,0x84,0x03,0x3e,0xb8,0xa1,0x5b,0x70,0x47,0xf3,0x49,0x9d,0x84,0xcf,0x43,0x5d, + 0x22,0x0b,0x30,0xb5,0x17,0x62,0x5b,0xb9,0x97,0x03,0xe3,0x8f,0xf8,0x15,0xc4,0xd4, + 0xac,0xbf,0xe3,0x7f,0xd9,0x61,0x6c,0x8c,0x8b,0x21,0xcd,0x5c,0xb6,0x78,0xb8,0xe3, + 0x15,0x1e,0xe8,0x54,0x35,0x14,0x0d,0xf7,0xab,0x9b,0xc5,0xd2,0x8e,0x6a,0xa1,0xf2, + 0x98,0x1d,0xe7,0x85,0xb6,0xb8,0x2f,0x52,0xd0,0xff,0x15,0x93,0xf3,0x69,0xcd,0xc5, + 0x11,0xbe,0x70,0x11,0xf2,0xa4,0x15,0xb5,0x68,0x63,0x40,0xc3,0x91,0xa3,0x14,0x30, + 0x85,0xb5,0xd3,0x3f,0xce,0xe5,0x40,0xed,0xa0,0xd4,0x9c,0x55,0x8a,0x95,0x74,0x23, + 0x09,0x98,0x70,0xe5,0x4b,0x77,0x3e,0x21,0x92,0xd3,0x69,0x04,0xde,0xd4,0xd0,0x45, + 0x82,0x14,0x05,0x78,0x0e,0xbd,0x5d,0x61,0x6d,0xeb,0x62,0xcd,0xf4,0x85,0x33,0xe9, + 0x4a,0x34,0xdd,0x55,0x52,0x38,0x5d,0xb1,0xdd,0xfa,0x4b,0x71,0xd3,0x75,0x90,0x6a, + 0x84,0xb5,0xdc,0x8d,0x9b,0x9c,0xd6,0x78,0x9a,0x55,0xe8,0xaa,0x99,0xfb,0x78,0xeb, + 0x11,0x16,0x46,0x8f,0x55,0x53,0x44,0x90,0x01,0x28,0xe6,0x54,0x72,0x3b,0x16,0x6b, + 0xae,0xd2,0x96,0x4c,0x70,0x2b,0x0f,0xad,0x40,0x25,0xe5,0x5e,0x74,0x87,0xbb,0xea, + 0x9d,0x14,0xa9,0xa8,0xfa,0x94,0x61,0xbf,0x8a,0x9e,0xdf,0x80,0x9a,0x6f,0x04,0x37, + 0xc3,0x8d,0x9c,0x51,0x52,0x8d,0x06,0xb9,0x16,0x57,0xec,0x0e,0x86,0x6d,0x72,0x5c, + 0xc2,0x8c,0x31,0x3e,0x58,0x72,0x3c,0xb8,0x9a,0xdb,0x19,0xcd,0x4b,0x3f,0xeb,0x56, + 0xab,0x5e,0x07,0xed,0x90,0xb5,0x01,0xcd,0x65,0xe3,0x17,0x81,0x45,0xf5,0x4d,0x2a, + 0xd3,0xb2,0xd9,0xf0,0xbd,0x3e,0x5f,0xb9,0xd7,0xf2,0xcf,0x5c,0x5a,0x80,0x01,0x64, + 0xbb,0x35,0x5d,0x75,0x24,0xa9,0x0e,0x17,0xc9,0x66,0x4b,0x59,0x14,0x34,0x39,0x2c, + 0x69,0xc3,0x3d,0xe5,0x91,0x2a,0x3f,0xc2,0x66,0x60,0x62,0x50,0xae,0x8d,0xb2,0x39, + 0xfc,0x77,0xe5,0xf7,0xf8,0x03,0x7f,0x63,0xc0,0xee,0xc9,0x15,0x2b,0xf9,0xb3,0xc1, + 0x51,0x62,0x1b,0xa6,0xa1,0xe1,0xaf,0xc0,0x41,0x4e,0x06,0xac,0x34,0x65,0xd7,0x6f, + 0x00,0x5e,0x2b,0xa0,0x06,0xe9,0x63,0x60,0x5a,0xa8,0x8e,0x4e,0xbf,0xf5,0x68,0x78, + 0x3b,0x95,0x0f,0x84,0xb6,0x0a,0x1a,0x72,0x44,0x85,0x30,0x05,0x3b,0x4c,0x54,0xb3, + 0x8e,0x5d,0x2e,0xa1,0xb2,0xa0,0x4e,0xf1,0xe5,0x5b,0x5d,0xf4,0x8f,0xec,0x49,0x42, + 0x0a,0xe4,0x7a,0xa6,0xe7,0x87,0xd1,0x4b,0x2e,0xe4,0xe8,0x17,0xc6,0x6c,0x85,0x22, + 0xb9,0xca,0xe8,0x80,0x1f,0xe8,0x60,0xa1,0xa7,0xac,0xb2,0x6e,0x48,0xf3,0x14,0x2f, + 0xae,0xec,0xb2,0x9b,0xf4,0x63,0x3f,0x49,0x21,0x6d,0xe3,0x29,0x3e,0x6b,0xa9,0xff, + 0x67,0xee,0x97,0xe0,0x75,0x4b,0x0b,0xcb,0xc8,0xe6,0x7f,0xdf,0xd4,0xa5,0x15,0x33, + 0x2e,0xd6,0xd4,0x58,0x74,0xda,0xf1,0xd9,0x2d,0x6f,0x43,0x4c,0xde,0x85,0xc9,0xef, + 0xdb,0x92,0xdc,0x76,0x93,0x0a,0x68,0x6e,0x6d,0x8f,0x4e,0x5f,0x6e,0xae,0xd2,0x86, + 0xe4,0x7c,0x80,0x6f,0x6f,0xef,0x85,0x05,0xc2,0x4b,0x29,0x45,0x6f,0x18,0x1e,0xb4, + 0xbd,0xea,0xb7,0x8f,0xb4,0x25,0xc4,0x57,0xc8,0x77,0xe3,0xef,0x7f,0xe7,0x6a,0x3d, + 0xd0,0x20,0xfb,0xdf,0x3e,0x00,0x79,0x3b,0x81,0x8d,0x6d,0xfb,0xf7,0xc6,0x7e,0x8d, + 0x10,0x8f,0xec,0x6e,0x07,0x4d,0x62,0x8e,0x8f,0xb4,0xa2,0x8f,0x9f,0xb4,0x76,0x43, + 0x11,0x8e,0x1b,0xbb,0xc1,0xe0,0x86,0x4c,0x98,0xbd,0x18,0x32,0x77,0x98,0x9d,0xc4, + 0xaa,0x6d,0x5d,0xf5,0x5f,0xe8,0x0d,0x5c,0xd7,0x09,0x8f,0x17,0x16,0x5d,0x95,0xd4, + 0xab,0x62,0x6d,0xef,0x4c,0xf1,0xde,0x73,0xe1,0xf6,0xe7,0xa7,0x9d,0xc2,0x73,0x85, + 0xec,0xb7,0xa4,0xa4,0x74,0xbb,0x24,0xb3,0x1a,0xdf,0x8e,0x86,0x34,0x7f,0x36,0x00, + 0x4f,0x04,0x5b,0xea,0x31,0xec,0x1e,0xf0,0x96,0x53,0x43,0xbc,0x67,0xf1,0x6d,0xc7, + 0x0f,0x46,0xe3,0xff,0x36,0xaa,0x63,0xc7,0x69,0x6b,0xf1,0x1b,0xf6,0xea,0xad,0xf3, + 0xa5,0x9a,0x10,0x27,0xbf,0x6c,0x7d,0xb3,0xf7,0x7a,0xfb,0xb0,0xd9,0x2b,0xd9,0x0e, + 0x69,0xb7,0xe6,0x44,0x0f,0xa3,0xcb,0xd9,0x2b,0x5a,0xc8,0x87,0x4f,0x83,0xbf,0x70, + 0x88,0x26,0x53,0xed,0x3a,0x10,0x64,0x93,0x05,0xa8,0x39,0x7e,0x7b,0x59,0xfc,0x8b, + 0xcf,0xee,0x1f,0x6f,0xb8,0x9f,0x29,0x83,0xcd,0xf8,0x35,0xd9,0x71,0x7c,0x74,0x9b, + 0x44,0xa1,0xe3,0x7f,0xa9,0xd7,0x41,0xbd,0x8e,0x1e,0xae,0xae,0xc1,0x56,0x99,0x3a, + 0xed,0x3d,0xe6,0xe4,0x02,0xac,0x26,0xbb,0x12,0xd7,0x22,0xb0,0xed,0xc3,0x56,0x21, + 0x29,0xc7,0x45,0x7b,0xea,0xa3,0x41,0x68,0x6f,0x40,0xef,0xfc,0x93,0x5d,0x70,0x4f, + 0x8e,0x9c,0xc7,0xde,0x33,0xdd,0xf7,0x88,0x6e,0xb0,0x37,0xcf,0x61,0x5e,0xd1,0x5f, + 0x87,0x06,0x92,0x5b,0x9f,0xc1,0x1d,0xfa,0xee,0x8f,0x69,0x9c,0x3f,0xbe,0x60,0x44, + 0x71,0x8d,0x8a,0x00,0xb3,0x26,0x4a,0x21,0xe3,0x46,0x6f,0x24,0xaf,0x9f,0x70,0x92, + 0x04,0x6b,0x73,0xf6,0xb0,0xa9,0x67,0xd2,0xc3,0x42,0x67,0xcb,0x51,0x41,0x79,0x83, + 0x85,0x3b,0x09,0x1c,0x31,0xa8,0x1d,0x27,0x61,0xc8,0x6a,0xda,0xd8,0x62,0x31,0xc1, + 0x76,0x0c,0x09,0xf7,0xee,0xaa,0xac,0x53,0x80,0xc3,0x66,0xcb,0x2e,0x43,0x40,0xbf, + 0x02,0xfb,0x62,0x22,0x31,0x06,0x50,0x60,0x42,0x75,0xa8,0x94,0x19,0xc5,0x4c,0xaf, + 0xfc,0xfa,0x4c,0x50,0x30,0x70,0x06,0x59,0xcf,0x74,0xd8,0x0b,0xf0,0xc5,0xbe,0xbe, + 0x7d,0x26,0x98,0x6c,0x37,0x2d,0x4f,0x48,0xff,0x77,0x47,0x8f,0xd4,0x65,0xb6,0x50, + 0x7c,0x27,0x21,0xdd,0xa0,0x16,0x3f,0x58,0x7f,0x76,0xc8,0x64,0xe3,0x25,0x3a,0xd8, + 0xf3,0x07,0x42,0x71,0xda,0x2e,0x6a,0x4a,0x09,0x40,0x92,0xd3,0xa7,0x68,0x40,0xe3, + 0xaa,0x0f,0xa0,0x99,0x17,0xa3,0x62,0xba,0x4c,0xad,0x65,0x3c,0xa6,0x96,0x63,0x4d, + 0x00,0x07,0x0b,0x98,0x39,0xd5,0x6b,0x4b,0x8b,0x35,0x97,0x2d,0x27,0x95,0x5b,0x36, + 0x28,0x81,0x0f,0xbd,0x38,0x5b,0x41,0x38,0x6a,0x4d,0x9b,0xc2,0xd9,0x6b,0xbd,0x49, + 0x02,0x2c,0x7a,0xdc,0xbd,0x28,0x7c,0x41,0xe7,0x1d,0x82,0x2b,0xfb,0xf3,0xb5,0xa7, + 0x03,0x2d,0x4e,0xba,0x70,0x3c,0x14,0x78,0x4b,0x4d,0x4f,0x42,0x6f,0x2f,0x47,0xb6, + 0x75,0x2e,0xc5,0xa5,0xa2,0xa5,0x55,0x45,0xf6,0x1f,0x67,0x0f,0x21,0x9b,0xb4,0xa6, + 0x74,0xf0,0x4c,0x2f,0x70,0x1e,0x5d,0x79,0xcb,0x4f,0xc4,0x26,0x59,0x6b,0x7c,0x02, + 0x21,0x52,0xe4,0xc0,0x76,0x3d,0xef,0x42,0xc1,0xda,0x94,0xa4,0x8f,0x70,0x34,0x40, + 0xda,0x1e,0xec,0xd0,0x29,0x3c,0x9c,0xd2,0x22,0xee,0x9c,0xb4,0x8e,0x71,0x3d,0x51, + 0x1f,0x1d,0x7a,0x25,0x11,0x42,0x6a,0x43,0x62,0x1a,0x95,0x5a,0x0f,0x72,0xb9,0xf3, + 0xe2,0xe4,0xc7,0x6e,0x12,0x3e,0x65,0x33,0xe4,0x93,0x9d,0x4a,0x0e,0x73,0x44,0xc0, + 0x22,0x14,0x55,0xdb,0x0e,0x8f,0x1c,0xe0,0x55,0xc8,0x6b,0x7f,0x87,0xf2,0x4c,0xd1, + 0x23,0x15,0x9e,0x52,0xe7,0xa4,0x64,0x90,0x67,0x71,0x9d,0x70,0x51,0x19,0x41,0xc1, + 0xaa,0x16,0xc1,0xfa,0xde,0x74,0x65,0x63,0x6a,0x8e,0xd5,0xa5,0xb4,0x38,0x49,0xd0, + 0xa3,0x17,0x6a,0xec,0xd0,0x9d,0x5f,0x51,0xed,0xc7,0xe3,0xd9,0x50,0x12,0x7e,0xea, + 0x6b,0xe6,0x8c,0x8d,0x9b,0xc5,0x2e,0x78,0x93,0x57,0x69,0xac,0x87,0x87,0x36,0x48, + 0xde,0x16,0x0b,0x1e,0x3c,0x89,0x54,0x43,0xca,0x5f,0x9e,0x43,0x79,0x79,0x7f,0x0b, + 0xa9,0x58,0x2b,0x08,0x9a,0x37,0x77,0xed,0xfc,0x57,0x68,0x52,0xf8,0x7a,0xbb,0xfb, + 0xea,0x64,0xb7,0x4d,0x42,0x34,0x97,0xa5,0x48,0xd1,0x60,0x42,0xf9,0x84,0x42,0xc8, + 0x22,0x3c,0xd0,0xf9,0x89,0x71,0x36,0xea,0x67,0xd7,0xe8,0xc1,0xd9,0x3e,0xb1,0x27, + 0x2b,0xe2,0xc8,0xf5,0xc7,0x2c,0xb6,0x70,0xe3,0xdd,0xa6,0xdb,0x92,0xcc,0x47,0x36, + 0x55,0xe1,0x9f,0xc9,0x93,0x80,0xd7,0x0b,0x6f,0x3c,0x87,0x2e,0x13,0xef,0x4f,0x26, + 0x54,0x1f,0xc9,0xf5,0xd8,0x37,0xf7,0x71,0xd8,0x04,0xa7,0xec,0x97,0x56,0xd7,0xe0, + 0x86,0xc8,0xc0,0x42,0x1c,0xad,0x60,0x33,0xa5,0xcf,0xb0,0xd9,0xab,0x1f,0x9c,0xe2, + 0x09,0x8e,0xa2,0x17,0xb6,0x5c,0x58,0x92,0x1f,0xce,0x47,0x36,0x55,0x1e,0x39,0xf3, + 0x85,0x8d,0xeb,0xfc,0x37,0xaf,0x51,0x83,0xfe,0xcd,0xb1,0xd8,0x2b,0xe2,0x49,0x57, + 0x92,0x0e,0x83,0x92,0x9b,0xc1,0x59,0x93,0xd9,0xcc,0x46,0xc8,0x2a,0xe3,0x64,0xbd, + 0x0e,0x7b,0x9e,0x73,0x25,0xa0,0x36,0x62,0x46,0xc4,0x3e,0x04,0xad,0x88,0x97,0xad, + 0x0f,0x85,0x44,0xc9,0x16,0xe5,0x61,0x72,0x47,0x05,0xf8,0xb6,0x05,0xa7,0x65,0x42, + 0x8e,0xa6,0x59,0xb8,0x7f,0x47,0x62,0x63,0xc6,0xe6,0x4e,0xfc,0x23,0x60,0x69,0x53, + 0x87,0xa7,0xf5,0x34,0xf4,0x0d,0x1d,0x73,0xc7,0x95,0xa9,0xb4,0x76,0x78,0x5a,0x88, + 0x09,0x42,0xe8,0x0f,0x3e,0xa5,0x52,0x8a,0x20,0xc7,0xb2,0xd1,0x5c,0xe8,0x12,0xca, + 0x72,0x86,0x92,0xce,0xe6,0xa6,0x70,0xc1,0xee,0xcf,0x45,0xc1,0xa2,0x16,0x5b,0x89, + 0x89,0x8e,0x26,0x8d,0x99,0x0a,0x53,0x6a,0x79,0xc7,0xb3,0xd0,0xdc,0xea,0x9f,0x79, + 0xce,0x54,0x93,0x4f,0x95,0xa4,0x37,0x50,0x6c,0x41,0xbb,0x3f,0x22,0xeb,0x62,0x4b, + 0x0e,0x8c,0xf4,0x7b,0xad,0xe1,0x02,0x6a,0x4e,0x4e,0x46,0x0c,0xa5,0x19,0x6e,0x5a, + 0x0f,0xad,0xd0,0xa5,0xe3,0x4c,0x43,0x7a,0x0f,0x62,0xe5,0x25,0xdd,0xe9,0x67,0x4b, + 0x8e,0xae,0xbb,0x4b,0xb7,0x10,0x18,0x6b,0xce,0x54,0xe4,0x51,0xae,0xac,0x6b,0x5a, + 0x87,0x8f,0x2b,0xef,0x19,0x7b,0x78,0x7b,0x93,0xa4,0xb2,0x1d,0x24,0x83,0x5c,0xe0, + 0x67,0x2f,0x9c,0xd6,0x3c,0xbf,0x4b,0x40,0xe6,0x98,0xb4,0x59,0x8b,0xf0,0x16,0x70, + 0x89,0x9e,0xa8,0x96,0x3d,0x91,0x44,0xd0,0x24,0x91,0xbc,0xb6,0x75,0x0e,0x5d,0x01, + 0xa1,0x13,0x35,0x86,0xb4,0x92,0x31,0xc1,0xa7,0x0d,0x4a,0x58,0xf4,0x0d,0x4d,0xd3, + 0x09,0x13,0xad,0x97,0xb5,0x93,0x45,0x31,0xe0,0x73,0x42,0xb7,0xf5,0xf3,0x64,0x3d, + 0xd9,0x94,0x73,0x42,0x14,0x84,0xce,0x1d,0xe4,0x93,0x64,0x0e,0xb2,0xb6,0x6c,0xd2, + 0x27,0x6a,0xbc,0xd2,0xde,0xc4,0xfc,0xf0,0x7b,0xce,0xc2,0xdf,0x36,0xf1,0x65,0x3c, + 0xa6,0x69,0xdb,0xf2,0x15,0xf4,0x8e,0x81,0x9b,0xdf,0xa5,0xe7,0x0b,0xf9,0x92,0x2c, + 0x58,0x68,0x95,0xa4,0x83,0xf5,0xdf,0x95,0x18,0xd1,0x83,0xc2,0x0a,0xfe,0x5e,0x08, + 0x29,0xc1,0xa2,0x8e,0x3c,0xb8,0x0e,0x7a,0x9b,0xd7,0x49,0xae,0x83,0x07,0x8e,0xf8, + 0x6c,0xd9,0xae,0x61,0x3d,0x46,0x5e,0xfe,0x75,0xd4,0x41,0xbe,0x7d,0xf9,0x1d,0x69, + 0x2e,0xb2,0xa3,0x70,0x43,0xba,0x0f,0xfb,0xe8,0xd5,0xb7,0x50,0x03,0xfa,0x57,0x19, + 0xac,0xf8,0x50,0x60,0xbd,0xbb,0x75,0x45,0x4e,0xd6,0x40,0x40,0xfd,0xfb,0x66,0x35, + 0x2e,0x63,0xb6,0xcf,0xc3,0xb3,0x82,0x47,0xcf,0x25,0x72,0xab,0x12,0xfe,0x91,0xda, + 0x2f,0x62,0xf9,0x3c,0xd6,0x2c,0x96,0x72,0x5c,0x86,0xda,0xa2,0x96,0x1c,0x98,0xcb, + 0xae,0x61,0x27,0x6f,0xba,0x13,0x6f,0xfb,0x13,0xd1,0xa7,0x67,0xee,0xf8,0x6f,0x24, + 0xaf,0x9f,0x2f,0x7f,0xb7,0x42,0xc5,0x1b,0xa9,0xc4,0x87,0xfd,0xb7,0x72,0x60,0x03, + 0x55,0x0f,0x15,0x35,0x64,0x8f,0xcf,0xde,0x64,0x5b,0x0f,0x24,0x50,0x60,0x49,0x0d, + 0x32,0x5a,0xf6,0x2d,0xe0,0xa1,0xe0,0xb4,0x18,0x29,0x58,0xb4,0x2c,0x61,0x51,0x1c, + 0x8c,0x03,0x12,0x77,0xfa,0x93,0xf2,0x47,0xf3,0x27,0x91,0xa7,0x3e,0xdf,0xb3,0xf1, + 0xd9,0x18,0xf4,0x66,0xad,0x17,0xa0,0xd3,0x6d,0x3e,0x99,0x35,0xd1,0x65,0x0a,0x80, + 0x3a,0xa9,0xc0,0x84,0x16,0x09,0x1a,0x19,0xc0,0xe3,0xc3,0xa3,0x90,0xe5,0x03,0xbd, + 0xfc,0x88,0x52,0x6c,0x9c,0x88,0x62,0x8d,0xe2,0x9e,0xe6,0x4c,0xdc,0xe3,0x0d,0x21, + 0x9e,0xa9,0xf7,0x7a,0xaa,0x64,0xf7,0xe5,0xc0,0x2f,0xd9,0xf8,0x52,0x86,0x36,0xac, + 0x7c,0x45,0x5c,0xc7,0x30,0x8a,0xde,0x8a,0x30,0x05,0xb9,0x35,0x95,0xec,0xa0,0x6e, + 0x2b,0x18,0xfa,0x3e,0xec,0x27,0x6a,0xc0,0xac,0x05,0x64,0x5f,0x5e,0x6a,0x8e,0x9c, + 0x2a,0x15,0x31,0xad,0x65,0x86,0x28,0xc7,0x6d,0x52,0x9a,0x2f,0x56,0x13,0x5a,0x20, + 0x2d,0x03,0x95,0xad,0x73,0x29,0x11,0xd8,0x6b,0x5a,0x0c,0x2d,0xd8,0x6a,0x9b,0xf1, + 0x1f,0x46,0x1c,0x05,0x19,0xe5,0xa9,0x5f,0x36,0x30,0xa5,0xf0,0x56,0xcd,0x5e,0x3a, + 0xe3,0xc6,0x53,0xde,0x1a,0x26,0x18,0xb4,0xc7,0x0e,0x2a,0x5d,0x62,0x2e,0xe6,0xc7, + 0x08,0x9d,0x71,0xce,0x1b,0x25,0x04,0xa1,0xb4,0x0c,0xa2,0x8c,0x05,0xcc,0x01,0xb6, + 0x63,0x44,0xc2,0x32,0x58,0x21,0xd4,0x83,0xcb,0xce,0xc3,0xed,0x7b,0xec,0x6d,0x9d, + 0xd8,0x74,0x4b,0x9b,0x8d,0x82,0x9b,0xa9,0xb2,0x54,0x4d,0xf9,0xfb,0x4c,0x1f,0x0a, + 0x23,0x00,0xbc,0x7b,0xb3,0x3d,0x2e,0x5a,0x91,0x3c,0x59,0xa6,0xeb,0xd4,0x88,0x6d, + 0xde,0x50,0x2f,0xa9,0xed,0x32,0xdc,0xe9,0x5d,0x13,0x70,0x27,0x76,0x7b,0x5c,0xba, + 0x05,0x19,0x7e,0x01,0xec,0xfb,0x73,0x99,0xe3,0x82,0xd9,0x7d,0x19,0xe8,0x1d,0x34, + 0xf0,0x08,0xd4,0x0b,0x14,0xcc,0x12,0xec,0xe0,0x33,0x8e,0xc6,0xfe,0x7a,0x1c,0x44, + 0x7e,0xdd,0xa6,0xa4,0xdb,0x65,0x84,0x92,0x89,0xb5,0xee,0x17,0x1e,0xff,0xf7,0x60, + 0x2b,0xba,0xec,0x85,0xbe,0xc8,0x53,0xb0,0x67,0x78,0xcc,0x55,0xd2,0x7c,0x7f,0xfc, + 0x49,0xec,0xa7,0xcc,0xb3,0x76,0x6b,0xd4,0x6f,0xf0,0xf4,0xd4,0x9e,0x34,0x86,0x53, + 0x4d,0xaa,0xaf,0xf7,0x46,0xb1,0x75,0x01,0xbd,0xf6,0x9f,0x05,0x54,0xd6,0x32,0xee, + 0x6b,0xe8,0xdf,0xab,0x9f,0x28,0xc9,0x56,0x4c,0xc8,0x15,0x5f,0x67,0xd5,0x3c,0xfe, + 0x9e,0x09,0xf1,0xe3,0x3f,0x81,0x25,0x7f,0xb3,0x51,0xa4,0x53,0x02,0x86,0xf8,0x75, + 0xa8,0x01,0x3f,0x77,0xa8,0x77,0x37,0xd3,0x9b,0xea,0x5d,0x5f,0xb8,0x85,0xb7,0x76, + 0x52,0x87,0x03,0xe7,0x1a,0x5e,0x9c,0x3d,0xb0,0x2a,0x5f,0xdc,0x18,0xd6,0x86,0x18, + 0x09,0x07,0xc6,0x0c,0x6a,0x91,0xc0,0x6c,0x4a,0x7f,0x40,0x68,0x5a,0x7e,0x8e,0x08, + 0x38,0x1b,0x5f,0x4e,0x37,0x35,0x06,0xfc,0xc2,0xca,0x32,0xcd,0x17,0x3f,0x42,0x4d, + 0xa8,0x8c,0x52,0x5f,0x3b,0x93,0x6f,0x1a,0xd2,0xd1,0xef,0x0d,0xee,0xf5,0xb9,0xa2, + 0xad,0x95,0x4f,0xdf,0x99,0x51,0x05,0x89,0x83,0x6e,0xcf,0xbf,0x98,0x5f,0xdf,0xea, + 0xe4,0xcd,0x13,0x3b,0xe8,0xa3,0xcf,0x50,0xbf,0x82,0xfa,0xe6,0x74,0x44,0x84,0x8d, + 0x66,0x85,0x2c,0x92,0x17,0x33,0x80,0xcd,0x7a,0xe1,0x54,0xa5,0x52,0xeb,0x5a,0x0b, + 0x21,0x3d,0x9b,0xfd,0x6f,0xb9,0xf9,0xd0,0x18,0x53,0xfd,0xff,0x3d,0x78,0x50,0x69, + 0xe4,0x87,0x12,0x55,0x34,0x5e,0x66,0x2a,0xc3,0x89,0x79,0x0c,0x86,0x16,0x64,0x30, + 0xfd,0x7f,0xf1,0x96,0xb5,0x1b,0x72,0xe6,0x44,0xf4,0xaa,0x99,0xf5,0xe0,0x6e,0x9f, + 0x87,0x8b,0x50,0x66,0xb6,0x3a,0xe8,0xd2,0x59,0x95,0xa0,0xf2,0xe8,0x50,0x65,0xc7, + 0xaf,0x0b,0xf9,0xd2,0xa5,0xec,0xd6,0xba,0x8e,0x7c,0x37,0x0c,0x95,0x76,0x09,0xe4, + 0x3e,0xc5,0xd6,0x10,0x45,0xaf,0x20,0x8b,0x22,0xa9,0xec,0x48,0xbb,0xa5,0x43,0xca, + 0x00,0x73,0x8a,0x6c,0xe8,0x19,0x4c,0x71,0xb1,0x74,0x7f,0xaa,0x77,0x92,0x92,0xe5, + 0x80,0x34,0x07,0x50,0xe8,0xf5,0xd6,0xa8,0x41,0xc1,0x7a,0xf3,0x89,0x49,0xdc,0x2f, + 0xbf,0x3c,0x14,0x33,0x01,0x57,0x9f,0x50,0x06,0x5b,0x73,0xff,0x78,0x15,0xcc,0xeb, + 0x0d,0x94,0x91,0xf4,0x2e,0xa5,0xbf,0xc6,0x3a,0x8a,0xf0,0x3d,0x30,0x4b,0x28,0xaa, + 0x3d,0xbc,0xe1,0x31,0xdc,0x3e,0x10,0x63,0x4f,0x8c,0xfc,0xd0,0x5f,0xfc,0x9c,0x31, + 0x09,0x07,0xe8,0xa2,0x1f,0x56,0x21,0x58,0x78,0x3b,0x6c,0xfa,0x16,0x3a,0xa3,0xcb, + 0xdc,0x88,0x58,0xdd,0x9e,0xa4,0x4f,0x01,0xfd,0xda,0x76,0x54,0xe6,0x1b,0xa6,0x7c, + 0x89,0x05,0xa8,0x98,0x76,0xde,0x26,0x9d,0xc9,0xee,0xfd,0x4a,0x56,0x63,0x9d,0xd8, + 0x22,0x20,0x9b,0x64,0xc8,0xb3,0xf4,0xfb,0x39,0xd8,0xfa,0x36,0x8b,0x5d,0x66,0x70, + 0xb4,0x6c,0xba,0xf4,0x55,0xa5,0x7f,0xb0,0x9c,0x5c,0xbf,0xa5,0x36,0x8b,0x89,0xfd, + 0x65,0x8d,0x35,0xf8,0xdc,0xbf,0xb1,0x5e,0x13,0x93,0xff,0xe0,0x2a,0xf8,0x07,0x43, + 0xf9,0x8b,0xd3,0x91,0x54,0x30,0x43,0x8a,0x0e,0x02,0x87,0x58,0x8e,0xd3,0x3c,0x46, + 0x7a,0x5d,0xda,0xeb,0xe8,0x19,0x0d,0x84,0x8d,0xc5,0x8c,0xf7,0x1a,0x59,0xd7,0x62, + 0x2f,0x3a,0x2c,0xf7,0x46,0x40,0xbc,0xd2,0x08,0xd8,0x6c,0x07,0x22,0xf1,0x5f,0xfe, + 0x4d,0xbf,0x74,0x59,0xb7,0x86,0x2f,0xa4,0x8e,0xe7,0x63,0x55,0xaa,0x88,0x75,0x57, + 0x86,0x2f,0x78,0xe9,0x83,0xb3,0x00,0xc8,0xdf,0x22,0xa3,0xaa,0xf7,0xec,0x58,0xa7, + 0x1f,0x7d,0xd4,0x7d,0xb0,0xfa,0x48,0x97,0x87,0xdb,0x01,0x7a,0x7a,0xd1,0xbb,0x5a, + 0x65,0xdb,0x6e,0x1e,0x72,0xbf,0x59,0x7a,0x05,0x9b,0x91,0xad,0x72,0x83,0x9f,0x74, + 0x23,0x3c,0xed,0x6f,0x8f,0x90,0x04,0x93,0x1d,0xb4,0x8d,0xbe,0xaf,0xfe,0x20,0x5a, + 0xac,0xfb,0x59,0xf4,0xbb,0xb9,0x30,0x96,0x4c,0x74,0x81,0x72,0x72,0x5d,0xa6,0x1a, + 0x57,0x9a,0xe4,0xf5,0x02,0x29,0xe0,0x6e,0x07,0xc4,0x2a,0x1e,0x01,0xb3,0x72,0x9d, + 0x29,0x6d,0x49,0xe6,0x86,0x37,0xd2,0x89,0x53,0x5b,0xc4,0x16,0x3c,0xb2,0x11,0xdc, + 0xa8,0x14,0x76,0x4b,0xf3,0x60,0xd4,0xc7,0x32,0xaf,0xf6,0x1f,0x01,0xb1,0x16,0x1b, + 0xb7,0xdd,0xec,0x3f,0xa7,0x12,0x77,0x88,0xdb,0x59,0xa6,0xa3,0x58,0xbe,0xb8,0xff, + 0xf4,0x11,0xfe,0x03,0x34,0x8f,0x6e,0x27,0x64,0x93,0x93,0xa0,0x7e,0x86,0x9b,0xe3, + 0x85,0x8c,0xf6,0x13,0x35,0xaa,0xc8,0x17,0xe0,0xee,0xa0,0xc7,0x77,0x65,0x07,0x29, + 0xe3,0x0a,0x21,0x77,0xf2,0xa5,0x6f,0x26,0x61,0xed,0xa9,0xd6,0xfa,0x07,0x5b,0x12, + 0x6a,0x67,0x6b,0x24,0xfd,0x8c,0xcd,0xf6,0x0b,0xb2,0xcf,0xb1,0xff,0x85,0xa4,0x22, + 0xf5,0x61,0x57,0x37,0x30,0x87,0x28,0x64,0xa2,0xc5,0x7c,0x40,0xbb,0x85,0x48,0x2e, + 0x62,0x01,0xe8,0xd2,0x15,0xf6,0x20,0xc0,0xd9,0xb0,0xca,0xa6,0xb8,0x21,0x79,0xbe, + 0x0d,0x80,0x52,0xb6,0xe6,0x16,0x39,0x92,0x46,0xeb,0x8f,0x87,0xd6,0xe3,0x2b,0x53, + 0x82,0x65,0x19,0x37,0x60,0x42,0xf9,0x82,0xe5,0xb3,0xe7,0x97,0xb1,0x62,0x92,0xf8, + 0xd8,0xb9,0x22,0x7e,0x7a,0x4f,0x2c,0x14,0x29,0x4c,0xaa,0xd2,0xf4,0x65,0x78,0xeb, + 0x85,0x04,0x8e,0xf1,0x11,0x69,0x3a,0xb2,0x6d,0xe2,0x29,0x45,0xa5,0xb0,0x7d,0x0f, + 0x69,0x89,0xfd,0x0a,0xbc,0x91,0x6a,0x5a,0xee,0xc3,0x6e,0xa9,0xba,0x81,0xf4,0xe9, + 0x19,0xba,0x8c,0x0f,0x72,0x4f,0x63,0x29,0x29,0xb4,0x20,0x98,0x13,0x66,0x1b,0xa9, + 0xef,0xb3,0xfa,0xb7,0xeb,0x40,0x86,0x94,0x94,0xb7,0xac,0x6b,0x7e,0xb7,0xcb,0x27, + 0x63,0x8e,0x35,0x1b,0xf2,0xdc,0xc4,0x74,0xaa,0x72,0x49,0x83,0xae,0xce,0x83,0xf9, + 0x02,0x04,0x07,0xb3,0x63,0x4c,0x39,0x52,0xb2,0x0c,0xd3,0x1e,0xbc,0xcf,0x35,0xe9, + 0x7e,0xac,0x2c,0x2e,0xef,0xf9,0x65,0xad,0xab,0x90,0x8d,0x83,0x26,0xce,0x7a,0x87, + 0x81,0x51,0xfa,0x21,0xdb,0xb3,0x6a,0xa7,0x44,0xfd,0x33,0x00,0x76,0x13,0xac,0xe2, + 0x43,0x96,0xbe,0x87,0x92,0x92,0x0f,0x43,0xe5,0xdc,0x3c,0xd6,0xc6,0x14,0x5f,0x8a, + 0xd8,0xbd,0xba,0x96,0xf7,0x3d,0x83,0x90,0x41,0xd3,0x71,0xe7,0x7c,0x7e,0x73,0x96, + 0x00,0x52,0xf3,0x21,0xda,0x3c,0x4f,0x03,0x0a,0x37,0xa5,0x5a,0x9a,0x7c,0x44,0x44, + 0x76,0x45,0xbd,0xb7,0x10,0xbd,0xf4,0x93,0xc1,0xd7,0x86,0xe2,0xba,0x17,0x8c,0x60, + 0x41,0x6a,0x0c,0x68,0x15,0x38,0x27,0xd7,0xc2,0xea,0xe2,0xdc,0x75,0x77,0xe6,0x64, + 0x7e,0x95,0xe5,0x4f,0xb3,0xa4,0xb2,0x12,0x6e,0x5b,0x71,0x14,0x51,0x36,0xf6,0x61, + 0x47,0x48,0x36,0xf2,0x12,0x2c,0x03,0x13,0xe7,0x6a,0xed,0x97,0x04,0x12,0x5c,0x86, + 0x50,0xb7,0x06,0xf7,0x3e,0x5b,0x86,0xdb,0x04,0xf9,0x16,0xdf,0x0c,0xfd,0x70,0x9f, + 0x88,0x58,0x3a,0xfe,0xd2,0x3a,0xbe,0xca,0x0b,0xde,0xa0,0x5e,0x1b,0x5c,0xa7,0xfb, + 0xca,0x9d,0x73,0xef,0x53,0xcb,0x2f,0x99,0xfd,0xf5,0x85,0x7f,0x13,0x3e,0x71,0x9e, + 0x08,0x84,0x4f,0x2d,0xdb,0xc4,0x61,0xbe,0xcd,0x5d,0xe1,0xba,0x58,0xa4,0xe9,0xa7, + 0xf7,0xc3,0x46,0x92,0xb7,0x5e,0x64,0xd8,0xf9,0xf3,0xee,0xdd,0x5c,0xd3,0x1c,0xe2, + 0x05,0x5f,0x31,0x1b,0xd2,0x1e,0xb9,0x0b,0xe7,0x50,0xa0,0x5d,0x5f,0xdc,0x87,0x79, + 0x89,0xab,0x6c,0x48,0x29,0x01,0xf7,0x9a,0x49,0xdd,0x07,0x93,0x90,0x5d,0xd7,0xea, + 0x8f,0x53,0x28,0xae,0x99,0xe9,0xa6,0xde,0x4a,0x33,0xce,0x0e,0x7f,0xf2,0x5e,0x04, + 0xe5,0x03,0x98,0xf5,0x32,0xc5,0x83,0xc0,0x3f,0xe0,0xcf,0xdc,0x52,0x30,0xd7,0x60, + 0x2b,0x5e,0x05,0x69,0x88,0xfd,0x65,0x38,0x41,0x71,0x07,0x74,0xf4,0x34,0x53,0xf0, + 0x08,0xc3,0x99,0xf4,0xba,0xe3,0xec,0x22,0xf3,0x45,0x5c,0x59,0x55,0xef,0x17,0x3f, + 0x0a,0x75,0x12,0x59,0x74,0x9c,0x1b,0xcf,0x45,0x38,0x2e,0x08,0xf7,0x9f,0xb4,0xb1, + 0x28,0x24,0xa8,0x42,0x91,0x15,0x8f,0x09,0xcb,0x32,0xc8,0x99,0xa3,0x87,0xa8,0xf7, + 0xfc,0x8f,0x96,0xf7,0xe6,0x03,0xd8,0x61,0x61,0xa1,0x86,0x70,0x34,0x20,0xf2,0x62, + 0xfb,0xe8,0x4d,0x3c,0x5c,0x57,0x39,0x13,0x0e,0xa5,0x0a,0x97,0xe6,0x17,0x6a,0xd7, + 0xa9,0x4a,0x7a,0xa4,0xb5,0xbc,0x27,0x91,0xc3,0xfa,0x2a,0x84,0x5b,0xa6,0x99,0x7a, + 0x8c,0x97,0xdb,0x2a,0xf5,0x19,0xbc,0xd3,0xe1,0x8a,0x0d,0x61,0x5a,0x6b,0x70,0x15, + 0x75,0x26,0xb9,0xbb,0xea,0xe8,0x60,0x53,0x35,0x66,0xd2,0x5c,0xaa,0xab,0x79,0x09, + 0x1e,0xcb,0xb5,0x6d,0x63,0x07,0xac,0xf8,0x31,0x8b,0x6d,0xed,0x7d,0x15,0x8b,0x69, + 0xef,0x0c,0x84,0x60,0x44,0x26,0x9b,0x49,0xaf,0x4c,0xa7,0xb2,0x09,0xc8,0x39,0x69, + 0x71,0x02,0x39,0x38,0xe5,0x07,0xb2,0xea,0xee,0xc1,0xac,0x8c,0x5a,0x69,0x85,0x64, + 0x21,0x78,0x06,0x2d,0x35,0x5b,0x24,0x98,0x4b,0xf0,0xc4,0x9c,0x3d,0x1b,0xb8,0x6d, + 0x8a,0xe7,0x9b,0x4b,0x7e,0x51,0x88,0x4c,0x6f,0x31,0xe1,0xbd,0x35,0xaa,0x39,0x60, + 0xc8,0x14,0xd5,0xbd,0xfe,0xab,0x49,0x4b,0x0c,0x60,0x85,0x78,0xfb,0x4b,0x90,0xe0, + 0xdf,0xf5,0x1f,0x36,0xd0,0x6f,0x14,0xdb,0xc5,0x5a,0x00,0xc4,0x1c,0xb3,0xd3,0x7a, + 0x2e,0xd3,0x1c,0x12,0x18,0x4f,0x44,0x5a,0x71,0x90,0x47,0x4e,0x75,0x4a,0x1d,0x7d, + 0x08,0x9f,0x65,0x22,0x51,0x29,0xb2,0x21,0xc6,0xa0,0x4a,0xd4,0xde,0x21,0x6d,0x46, + 0x44,0x3c,0x97,0x64,0xc1,0x1e,0x2f,0xb2,0x1a,0x5e,0x3d,0x33,0xa1,0xa2,0x73,0x2a, + 0x59,0xd9,0xec,0xc2,0xb1,0x05,0x13,0x19,0xd3,0x42,0xa6,0xc4,0x9d,0x90,0x94,0xa1, + 0x5f,0xf9,0x13,0x3e,0x99,0xf8,0x28,0x89,0xb1,0x7a,0x01,0x1a,0x77,0x4e,0x1b,0xfa, + 0xc5,0x69,0xb5,0xfe,0xac,0x0b,0x5a,0xa4,0x38,0x79,0xcd,0xc3,0x1f,0x3c,0x0b,0x02, + 0xa6,0xb7,0x7a,0x28,0xa5,0xfa,0x2d,0x53,0x0a,0xa7,0x97,0xd3,0x0b,0xe6,0xb5,0x79, + 0x50,0x37,0x35,0xc9,0xf6,0x72,0xe2,0x54,0x48,0xde,0x1a,0xc1,0xa2,0x07,0x74,0x86, + 0x15,0x36,0x6e,0x3b,0xc6,0x62,0xba,0x45,0x49,0x76,0xd6,0xb9,0xde,0x9c,0x77,0x78, + 0x86,0xdb,0xaf,0x8b,0xb5,0x5b,0x17,0xf2,0x4d,0x50,0x0e,0x31,0x7f,0xbe,0x8f,0xe9, + 0xcf,0x1c,0xaf,0xec,0xdb,0xb1,0x9f,0xc9,0x8f,0x5c,0x00,0x5d,0xfb,0x98,0xf6,0xb8, + 0xc5,0x4d,0xb4,0xce,0xc9,0xd2,0xda,0x98,0xa4,0xff,0x2d,0xee,0x97,0x36,0x7c,0x24, + 0x94,0x39,0xaf,0xb8,0xe9,0xb5,0x2e,0x09,0x4d,0x70,0xa5,0xfe,0x7b,0x4d,0x19,0xf6, + 0x47,0x54,0xbe,0x7c,0x1b,0x48,0x09,0x4a,0x0f,0x78,0x0a,0x03,0xfe,0x41,0x78,0x39, + 0x4f,0x34,0xeb,0xfb,0x30,0xfe,0x2b,0xca,0x93,0x70,0x53,0x8c,0xdd,0x59,0x9b,0x73, + 0x79,0x89,0xbe,0xb5,0xda,0x03,0x80,0x5f,0x9a,0xcb,0x42,0x1b,0x3e,0xff,0x12,0x12, + 0x93,0x40,0xee,0xb4,0xfa,0xa2,0x38,0xba,0x65,0x4c,0x23,0x76,0xf0,0x9c,0x21,0xeb, + 0x69,0xf3,0xff,0xb4,0x79,0xa1,0x31,0xcb,0x35,0xcb,0xee,0xa1,0x84,0x1c,0xba,0xb0, + 0x7d,0x40,0xb7,0xb0,0xf1,0x3f,0xe0,0x16,0x60,0x3c,0xb1,0x57,0x25,0xe0,0xc8,0x2c, + 0x61,0x24,0x16,0xd3,0x30,0x29,0xa7,0x82,0xc0,0x0c,0xc8,0x71,0xd0,0x4c,0x70,0x00, + 0x07,0x0a,0xe2,0xd1,0x50,0xc5,0x20,0x12,0x02,0x65,0xa0,0x07,0x63,0xe2,0x39,0xc3, + 0x83,0x64,0x41,0x54,0xe2,0xdb,0x9d,0x03,0x83,0x06,0xae,0x07,0x93,0x26,0x71,0x01, + 0xc3,0x08,0x99,0x37,0x97,0x87,0x21,0xf3,0xc6,0x7e,0x26,0x70,0xac,0x98,0x59,0x08, + 0x0e,0xd8,0x7d,0x7e,0x72,0x6b,0xbe,0x0c,0x99,0xb5,0x25,0x9d,0x5e,0x4b,0xda,0x3c, + 0xa8,0x96,0x1d,0x62,0xd3,0xf8,0x43,0xf8,0xec,0xe6,0xf2,0x5e,0xae,0x2b,0x92,0x17, + 0xa2,0xfe,0x78,0x4a,0x65,0x8c,0x38,0x52,0xe9,0x9a,0x82,0xef,0x79,0x95,0xbf,0x7b, + 0x06,0x8d,0x83,0x99,0x70,0x88,0xc9,0x31,0x6c,0xe4,0x1c,0x49,0xfd,0x6d,0x22,0x08, + 0x0c,0x01,0xd5,0x9f,0x76,0x51,0x08,0x69,0xe9,0x4a,0x42,0x1f,0x62,0xcd,0x72,0x08, + 0x2b,0x02,0x80,0xa2,0xb8,0x2b,0x56,0xef,0x0b,0x42,0xc0,0xf8,0x26,0xeb,0x49,0x48, + 0x29,0x6b,0xa3,0x0c,0x21,0x23,0xdb,0x11,0x69,0x48,0xc2,0x92,0xfe,0x95,0x73,0x09, + 0x8a,0x00,0xc7,0xa6,0x3a,0xa5,0x3b,0x3d,0xf7,0xcd,0xbb,0x39,0x95,0x62,0x94,0xc7, + 0xc9,0x81,0x87,0xf7,0x5a,0xb1,0x29,0x70,0x3c,0xfb,0xf4,0xe5,0x89,0x7d,0x99,0x03, + 0x59,0xce,0xde,0x24,0xce,0x9e,0x64,0x10,0x8a,0x72,0x96,0xb0,0xd2,0x77,0x63,0xbd, + 0x5f,0xbf,0x7a,0x76,0x9e,0x9f,0x6d,0x81,0x00,0xf6,0xdf,0x5b,0x53,0x7f,0x9d,0xf3, + 0x4a,0x62,0x5d,0xd2,0x58,0x50,0x7d,0xb3,0xb8,0x5e,0x91,0x56,0x50,0xf9,0xb4,0xa2, + 0x61,0xe4,0xfa,0xfc,0xbf,0xb2,0x34,0xa1,0x95,0x59,0xea,0x99,0xd1,0x11,0x44,0x72, + 0xd2,0x1a,0xdd,0xd5,0xb3,0x55,0x50,0x0b,0xc2,0xdd,0xb9,0x09,0xf0,0xd8,0x4f,0xe1, + 0x01,0x10,0xc4,0x85,0xfa,0x9d,0x1f,0x1a,0x41,0x50,0xeb,0x05,0x51,0xad,0xf9,0xaa, + 0x00,0x11,0x93,0xfd,0x4c,0x9a,0xdd,0x13,0x88,0xb6,0x4e,0xc5,0xfb,0xc8,0xb2,0xea, + 0xc3,0x89,0xe0,0xb1,0xd1,0x7b,0xd2,0x2d,0x66,0xd2,0x6d,0x4e,0xd9,0xf2,0x76,0x9c, + 0xc9,0x98,0xa8,0xa0,0x1f,0x9d,0x25,0x89,0xc8,0xd8,0xe0,0xde,0x3a,0xa6,0x97,0xfa, + 0xc4,0xb1,0xe1,0xb1,0xbb,0xfa,0x13,0xd0,0xc9,0x78,0xe8,0x4f,0x7a,0x52,0xe5,0xbd, + 0x16,0xa6,0x18,0x38,0x34,0x96,0xd6,0x4a,0x6d,0xd6,0xe7,0xdf,0xba,0xc4,0x4e,0x5d, + 0xd7,0x13,0x53,0x8b,0xf8,0x2c,0xd7,0x6c,0x04,0xba,0xec,0x5d,0x02,0xe3,0x36,0x5a, + 0x2e,0x39,0xac,0xd4,0x3a,0x9d,0xcf,0x87,0xaa,0x3f,0x84,0xfd,0xa5,0xc2,0x27,0x8d, + 0xf5,0x93,0xcf,0x4d,0x53,0x8f,0x47,0x8b,0xee,0xfe,0x17,0x98,0xfb,0x12,0x77,0x89, + 0xa3,0x10,0x91,0xf4,0xb7,0x3b,0x15,0xec,0xcb,0x52,0xe5,0x63,0x08,0xd2,0x21,0x78, + 0x65,0x84,0xb2,0x4c,0xeb,0x2d,0xe6,0xa0,0xc4,0xba,0x38,0x31,0xb5,0xef,0x42,0x23, + 0x35,0x2e,0x96,0xb3,0xcb,0x0c,0x80,0xc1,0x23,0xd1,0xf2,0xcd,0xf6,0xe7,0x43,0x01, + 0xa0,0x09,0xf7,0xb7,0x63,0xcc,0x11,0x3b,0xf7,0x5a,0xd1,0x66,0x21,0xef,0x89,0x61, + 0xe7,0x75,0x79,0x89,0x94,0x63,0x81,0xc0,0xab,0xc5,0xb5,0xd1,0x74,0x69,0x00,0x02, + 0x00,0x89,0x1b,0xa4,0xff,0xf5,0x08,0x46,0xa7,0x6b,0x0f,0x34,0x15,0x14,0x62,0x42, + 0xa4,0x83,0x6d,0x25,0x67,0x23,0x6b,0x81,0x3f,0xc3,0x86,0x4f,0x47,0xa8,0x6b,0x47, + 0x25,0x8b,0x4d,0xd5,0x86,0xae,0xe0,0x90,0xfa,0x69,0x61,0x8f,0x17,0xab,0xe1,0x63, + 0xe4,0xa7,0xe8,0x17,0xdf,0x0c,0xf1,0x36,0x66,0x4d,0x87,0x4b,0x9f,0xec,0x5c,0x0d, + 0xad,0xc9,0xf8,0xdf,0x6c,0xb7,0x12,0xf2,0xed,0xf7,0xcd,0xcc,0xde,0xc0,0xd5,0x69, + 0x67,0xea,0x7e,0x8d,0x77,0x04,0x42,0x1a,0xad,0x6d,0xc2,0xbc,0x54,0x36,0x1d,0xbf, + 0xe4,0x87,0x99,0xe9,0x11,0x07,0x19,0xfb,0x90,0x61,0x49,0x4d,0x9f,0x55,0xd0,0x64, + 0xed,0x9a,0x7b,0x8c,0xff,0xa3,0x43,0x07,0x26,0x3a,0x83,0xef,0x26,0xe4,0x1a,0xc8, + 0x0f,0xe1,0xf3,0x4a,0x9e,0xde,0x89,0x88,0xcc,0xe4,0xcc,0x8e,0x7d,0xac,0x50,0xb8, + 0x8d,0x85,0xeb,0x1e,0x57,0x20,0x02,0xf8,0x46,0xf2,0xec,0x1c,0xa0,0x40,0x1b,0xc9, + 0x8f,0xeb,0xdd,0x63,0x13,0x28,0x8a,0x09,0x8d,0x71,0xf5,0x12,0x37,0x3f,0x9f,0xb9, + 0x0d,0x87,0x95,0x77,0x1f,0x5f,0x43,0x2b,0xcb,0xc0,0xec,0xfb,0xa9,0x4e,0xc1,0x72, + 0xa4,0x8f,0x70,0x15,0x48,0x1f,0x66,0x05,0x62,0xf3,0xcc,0x24,0x7d,0x4f,0xbc,0x63, + 0x86,0xd1,0x3f,0x65,0x13,0xdd,0xbb,0xc8,0x0d,0xdc,0x84,0x66,0x8e,0xfe,0x1e,0xf3, + 0x24,0x84,0x71,0xf4,0x92,0x14,0xf6,0x4b,0xdb,0xd6,0x8d,0x77,0x03,0xfd,0x1f,0xa3, + 0x22,0xd2,0x93,0x26,0x7f,0x42,0x2f,0x0b,0x0e,0x97,0xdd,0xf6,0x71,0xfe,0x04,0x86, + 0xa6,0x99,0x61,0xb4,0xdd,0x85,0xf4,0xf3,0x5a,0x7a,0x67,0xd7,0xd7,0x0b,0xe4,0x06, + 0x44,0xf5,0x13,0x27,0x0f,0x4a,0x01,0x90,0x24,0x6a,0xa6,0x30,0x0b,0x5a,0x6f,0xc1, + 0x05,0x90,0xc5,0xd3,0xdd,0xa7,0xe3,0x8c,0x64,0xfe,0xcb,0xde,0xd8,0x29,0x15,0x51, + 0xa2,0xcd,0xd3,0xff,0xd6,0xf7,0x05,0x91,0xa6,0xf7,0x5d,0x07,0x6d,0x24,0x78,0x33, + 0x2c,0x3c,0xd8,0x3f,0xd5,0x3b,0x0c,0x1a,0xc2,0x9a,0xbc,0xaa,0xdf,0xfe,0x95,0xd4, + 0x98,0xfa,0x1d,0x3a,0xc1,0xda,0x86,0x49,0x0f,0xc9,0xde,0xff,0xf9,0xf4,0xed,0x37, + 0x88,0xc6,0xc1,0xb3,0x57,0x39,0x63,0x37,0xdf,0xe1,0xbf,0x0a,0x1d,0xf5,0x49,0xf9, + 0x16,0x84,0x6f,0x3e,0x8d,0x6e,0x87,0x48,0x87,0xb7,0xf5,0x44,0x5e,0xfd,0x1e,0x48, + 0x2b,0x95,0xfe,0xde,0xd7,0xad,0x0e,0x68,0x67,0x63,0x88,0xe9,0x8f,0xf3,0x34,0x25, + 0x8c,0x9b,0x93,0xbc,0x7e,0xfd,0x46,0xaa,0x67,0xd2,0xde,0xae,0xde,0x75,0x3d,0x36, + 0x0d,0xfb,0xbf,0xda,0x3c,0x96,0x4f,0x3b,0x15,0xd1,0x43,0x94,0x5d,0xf8,0x3f,0xf4, + 0x0e,0x15,0x97,0xac,0x87,0x30,0x21,0xce,0xfb,0x9d,0xdf,0x1d,0xdb,0xff,0xa8,0x38, + 0x33,0x12,0x6c,0x84,0xec,0x00,0x12,0x46,0x3c,0x0f,0x37,0xbb,0xbb,0xd6,0xc8,0x76, + 0x20,0xeb,0x59,0x0b,0x2f,0x95,0x41,0x20,0xe4,0x2f,0x2a,0x2b,0xbd,0xce,0xb9,0xe1, + 0xa9,0x19,0x2d,0x47,0x13,0xf6,0x2b,0xc9,0xd2,0x0d,0xcf,0xbf,0xd4,0xb6,0x59,0x11, + 0xc2,0x02,0x29,0x0f,0x1d,0xae,0x7b,0x41,0xc0,0xd1,0xaf,0xc4,0x31,0x23,0xe7,0x6d, + 0xda,0x95,0x67,0x79,0xf3,0x8b,0x31,0x20,0x52,0xd0,0x43,0x63,0xf3,0xfb,0xdb,0xa3, + 0x7f,0xaa,0xae,0x85,0x12,0x65,0xbb,0x1b,0xe4,0x29,0x8c,0x0e,0x25,0xca,0x7b,0xb2, + 0xfa,0xa9,0x93,0x36,0xf0,0x4a,0x46,0x7a,0xb6,0x5d,0x65,0x07,0xae,0xc9,0x19,0xd5, + 0xda,0xce,0xd5,0xba,0x7a,0xed,0x66,0xe2,0xe1,0xea,0x89,0x9d,0xa4,0xaa,0x11,0xc9, + 0x8f,0x99,0xfc,0x9a,0xf3,0xce,0xaa,0x18,0x9a,0x07,0x3a,0xa6,0xcc,0xfc,0x0e,0xe4, + 0x81,0xf2,0xe8,0x02,0xcf,0xdd,0xe2,0xd0,0x49,0x04,0x1e,0xfa,0xcb,0x6a,0xc3,0x69, + 0x98,0x44,0xdd,0x9e,0x88,0x85,0x4a,0x27,0xab,0x6a,0x36,0x36,0xb3,0x1e,0x23,0xf5, + 0x6d,0x70,0x6c,0xee,0x43,0x80,0x19,0xdf,0xe9,0x9b,0x78,0xc6,0x11,0x9c,0x3c,0xec, + 0xff,0x8f,0xbd,0xb4,0x1a,0x57,0xc5,0x18,0xca,0x53,0x2d,0x97,0xd5,0xc1,0x62,0x65, + 0xe0,0x49,0x94,0xf1,0x1f,0xd8,0x12,0x70,0x9b,0xbc,0xa3,0x0d,0x79,0x7b,0xe5,0xba, + 0xa0,0x85,0x13,0xbc,0xac,0x2d,0x68,0x19,0x4a,0x58,0x87,0xf6,0xb9,0x6a,0x11,0x5a, + 0xfd,0xfa,0x5c,0x63,0xef,0x6d,0x7c,0xd9,0xf8,0xd9,0xd3,0x6d,0xe8,0xe5,0x1a,0xdc, + 0xb2,0x1a,0x66,0x97,0x0e,0xd6,0x44,0x39,0x6a,0xdd,0x14,0x55,0xa2,0x30,0xd3,0xa5, + 0x5a,0x20,0xee,0x90,0xcd,0x75,0x8c,0xd6,0x9a,0xaa,0xc2,0x87,0x75,0xda,0x91,0x21, + 0xca,0x60,0xbf,0x76,0x7a,0x99,0x4c,0xa1,0x47,0x49,0x36,0x93,0x2c,0x97,0xcd,0x3d, + 0xa1,0x08,0x3e,0x92,0x65,0xe5,0x19,0x35,0xc4,0xf2,0xaf,0xb1,0x74,0x65,0xab,0xd3, + 0x04,0x50,0xfa,0x64,0x53,0x30,0x2d,0x1b,0xb3,0x89,0x00,0x77,0x2f,0xd9,0x34,0xd4, + 0x96,0x57,0x9c,0x70,0xfb,0x16,0x5e,0x82,0xdc,0x51,0xe2,0x50,0x12,0x71,0x63,0x60, + 0x2e,0xbd,0xa4,0x85,0xf6,0x92,0x7e,0x9b,0xc0,0xbb,0x5e,0x95,0x72,0x69,0x0d,0xf3, + 0x02,0xc8,0x19,0x3d,0x98,0xfa,0x9d,0x36,0x1a,0xd1,0xbc,0xb5,0xef,0xd3,0xe7,0xee, + 0xd7,0x76,0x21,0x13,0x53,0x8e,0x2c,0x57,0xe8,0x79,0x37,0xb6,0xe4,0xcc,0x2e,0x72, + 0x40,0xf8,0x2d,0xaa,0xe5,0xdc,0xd9,0x3a,0xe9,0xf3,0xff,0x1c,0xaf,0xc6,0x39,0xa1, + 0x76,0x91,0x07,0x7c,0x6a,0x7a,0x4e,0x2d,0x4d,0x51,0xc9,0xa2,0xbe,0x34,0x6e,0xd9, + 0xe9,0x55,0xd1,0xae,0xbd,0x90,0x27,0x69,0xb5,0xf0,0xa1,0x00,0x91,0x8c,0xf2,0xaa, + 0xd5,0xb8,0x39,0x8b,0xd3,0x5f,0xa9,0x92,0x0b,0x58,0x06,0xb0,0xb2,0x1f,0xea,0x29, + 0x88,0x5d,0xd0,0x78,0xa9,0x37,0x83,0x07,0xeb,0x3d,0x8c,0x1a,0x92,0xfe,0x15,0xcf, + 0x62,0x7d,0x20,0x3d,0x3a,0x21,0x35,0xeb,0xeb,0xde,0x58,0x05,0x85,0xd3,0xf6,0x5d, + 0xa9,0x1a,0xd3,0xae,0xfc,0xbe,0xf2,0x82,0x76,0xf2,0x1f,0x58,0x59,0xd2,0x31,0x11, + 0x4b,0x88,0xc3,0x02,0xe8,0xe4,0xb7,0x50,0xbb,0x82,0x67,0x35,0xa2,0x33,0x00,0xea, + 0xc9,0xc3,0x0f,0x21,0x7e,0x04,0xd0,0xb7,0xc5,0x41,0xcb,0x8e,0x9d,0xb2,0x07,0xcb, + 0x8d,0x39,0x12,0x00,0x40,0x67,0xa9,0x52,0xc5,0xd2,0x97,0x9c,0xae,0x46,0xe6,0xeb, + 0xf2,0x46,0x29,0xe6,0x75,0xe3,0x03,0xdb,0x51,0x8c,0x5b,0x24,0xeb,0x05,0xc0,0xb1, + 0x28,0x70,0x2a,0x29,0x9b,0x09,0x4d,0x84,0x66,0xa7,0xd0,0xef,0xdb,0x69,0xd1,0x0d, + 0x01,0x7f,0xc8,0x96,0x33,0xc9,0x06,0x74,0xa6,0x46,0xf8,0x88,0xda,0x48,0x33,0x31, + 0x31,0x7a,0xb1,0x37,0x16,0x20,0x61,0x93,0x51,0xf7,0x16,0x98,0x37,0x60,0xbb,0x18, + 0x7a,0xbb,0xd3,0xc4,0xbd,0x08,0x8b,0x80,0x4b,0xca,0xad,0xe8,0x22,0x6e,0xfd,0x22, + 0x0a,0xdb,0x0a,0x84,0x88,0x3c,0x6b,0xd6,0xa9,0x37,0x88,0xdd,0x96,0x43,0xd5,0xdd, + 0xe4,0x71,0xee,0xd8,0x8f,0xaa,0x60,0x38,0xfe,0x60,0x09,0x39,0x89,0x3f,0xd8,0xe3, + 0xfb,0x47,0x06,0x14,0xf7,0xde,0xdf,0x58,0x91,0x3c,0xd1,0x2b,0x20,0xae,0xcc,0xeb, + 0x0d,0x94,0x48,0xe4,0x55,0xf8,0xb0,0xb1,0xce,0xab,0x1c,0xa0,0xb6,0x5d,0x5f,0x8d, + 0xcc,0xec,0xb6,0x3c,0xd4,0xaf,0x8d,0x96,0x4e,0x8e,0xd2,0x84,0xb7,0xef,0xaa,0x03, + 0x69,0x00,0xbe,0xcd,0x31,0x00,0x78,0x24,0xeb,0x20,0xfc,0x96,0x0a,0xa0,0x6b,0x46, + 0x6f,0xf1,0x9d,0xef,0x11,0x03,0x74,0x2c,0x33,0xd5,0xe9,0x6d,0x4c,0xe4,0x13,0x7c, + 0x2c,0xa7,0x3b,0x2f,0x1f,0xb0,0xbf,0x25,0xc1,0xd1,0xf9,0x99,0x50,0x42,0x63,0x80, + 0x6c,0xd2,0x96,0x82,0xb1,0xa6,0x4c,0xae,0x84,0x2f,0xca,0x1b,0x9d,0x23,0x75,0x16, + 0x80,0x9a,0xf2,0x99,0x7b,0xff,0xdb,0xc1,0xc6,0x58,0x82,0x0f,0x1f,0x46,0x7d,0xcf, + 0x24,0xc4,0x04,0x9d,0x28,0x06,0x6c,0xa3,0x41,0xbc,0xe3,0x19,0x1f,0x21,0xaf,0x7b, + 0xbb,0xde,0xcc,0x37,0x63,0x0c,0x1d,0x59,0x86,0xd7,0xc3,0x0e,0x1c,0x60,0x5c,0x38, + 0x8a,0x99,0x1b,0x39,0xd7,0x37,0x6f,0xce,0x60,0x6c,0x24,0x04,0xda,0x59,0x8f,0x89, + 0xda,0x29,0xd4,0x29,0xc2,0xd6,0xc5,0x82,0x33,0xdc,0xa2,0x14,0x73,0x70,0xc9,0x5c, + 0x59,0x0b,0x1a,0x39,0x4b,0x17,0xe6,0x8c,0x45,0x86,0x21,0x05,0x1f,0x3c,0x16,0x57, + 0xfe,0x54,0x16,0xa4,0xcb,0x46,0xfd,0xb2,0x8b,0xc2,0x4e,0x15,0x9f,0x06,0xd9,0x88, + 0x28,0x63,0x9c,0x7d,0xfa,0x17,0x57,0xea,0x24,0x23,0xe0,0x14,0x97,0x6b,0x89,0x78, + 0xcd,0x66,0xd0,0x0c,0xc1,0xfd,0x2e,0xa7,0x2d,0x54,0x89,0x07,0x8e,0xf7,0x36,0x63, + 0xbe,0xd7,0x41,0x7e,0x76,0xaa,0x33,0x2f,0xdd,0x73,0x00,0x12,0x08,0x29,0x76,0x9a, + 0x0a,0x80,0x1c,0x98,0x69,0x6d,0x66,0xbb,0x4a,0x9a,0xd7,0x39,0x01,0xba,0x5d,0x28, + 0x82,0x21,0x98,0xc8,0xd7,0x6d,0xe3,0xdc,0x16,0xcc,0x88,0xd3,0x8b,0x5f,0x50,0xe3, + 0x4e,0x99,0x15,0xf9,0x9e,0x42,0xcc,0xc7,0x7f,0x18,0xac,0x9f,0x37,0xbc,0x1f,0x0c, + 0x64,0x4f,0x34,0x3c,0x32,0xb3,0xc5,0xd7,0x5e,0x4f,0x64,0x1c,0x8a,0x5e,0x16,0xa1, + 0xce,0x9b,0xc9,0xe2,0x3b,0x1b,0x2f,0xdf,0x3b,0x0e,0x58,0xd2,0x7a,0x6e,0x59,0x9f, + 0xa5,0x0b,0xe3,0xc4,0x14,0xb4,0x06,0x18,0x46,0xf8,0xee,0x22,0xdd,0xdd,0xf7,0x98, + 0xa4,0xbe,0x9b,0x72,0xea,0x20,0x5e,0x0b,0x7d,0x03,0xe1,0x4c,0xc3,0x6b,0x52,0xe9, + 0x2c,0x4f,0x0f,0xc3,0x9a,0x39,0x36,0x43,0x3f,0x4b,0xf7,0x23,0xb3,0x66,0x96,0xf1, + 0xa7,0x05,0xb1,0x11,0x14,0x01,0x45,0x34,0xf2,0x35,0x5a,0xc5,0xed,0x52,0xcf,0xdf, + 0xfd,0xa9,0xf8,0x14,0x1a,0x2b,0x06,0x1d,0xa9,0xbd,0xe8,0xb4,0xed,0x6b,0x37,0x22, + 0xc1,0x05,0xc2,0x14,0xb0,0x23,0x60,0x20,0x63,0x4a,0xe0,0x24,0x57,0x6a,0xca,0xdf, + 0x75,0x47,0xa1,0xe5,0x2e,0x2b,0xc1,0xe3,0x42,0xce,0xe9,0x35,0xda,0x69,0x32,0x16, + 0x7e,0xb1,0x99,0x44,0x32,0xaf,0xc9,0x0e,0xcd,0x25,0x06,0x9b,0xd5,0x9e,0x22,0xcc, + 0xa9,0x82,0xdb,0x1b,0xfd,0x46,0xaa,0xd6,0xb5,0x26,0xeb,0x4a,0xa7,0xe3,0x38,0xe7, + 0xf0,0x4b,0xbe,0x22,0x39,0x0b,0x09,0x28,0xa2,0xf8,0xca,0xbd,0x11,0xe2,0x84,0xf8, + 0x2b,0x4a,0xe1,0x0c,0x9b,0x6a,0xf0,0xe9,0x84,0xe7,0x84,0xa9,0xdb,0x11,0x04,0x8a, + 0x28,0x94,0x0c,0x66,0x97,0x2d,0x3b,0x30,0x81,0xda,0xd3,0x10,0x59,0xab,0x79,0x38, + 0x8a,0x13,0xc3,0xae,0xb6,0xa7,0x18,0xd5,0xb5,0x20,0xb0,0xe8,0x71,0xba,0xda,0xa7, + 0xf0,0xa0,0x4f,0x3e,0x58,0x22,0xca,0xdd,0xbc,0xb0,0x8a,0x58,0xba,0x62,0xf8,0x39, + 0x0a,0x18,0x44,0xaf,0x18,0x2d,0x0a,0xd7,0x6f,0xb8,0x13,0x8c,0x42,0x68,0xc4,0xc2, + 0xe8,0x0b,0xb3,0xdf,0xb9,0x0d,0x49,0xab,0x34,0x92,0xbb,0x3d,0xca,0xef,0x17,0x68, + 0xfe,0x5d,0xe1,0x44,0x91,0xb8,0x1c,0xb0,0x81,0x42,0xce,0x89,0x4c,0x6f,0x8e,0xb0, + 0x51,0x71,0x31,0xd3,0xfb,0xd9,0x1a,0x58,0x99,0xfc,0x09,0x5e,0xd4,0x1d,0x5d,0x84, + 0x82,0x83,0x8d,0x67,0x8f,0x12,0xed,0x85,0x1d,0x59,0x2d,0x5a,0x93,0xe3,0xcd,0xe8, + 0x35,0xbe,0x85,0x91,0x19,0x8d,0x0a,0x57,0xd2,0xe6,0x7a,0x4b,0x55,0x9e,0x1d,0x6a, + 0xcb,0xcc,0xfc,0x14,0xff,0xbc,0xad,0x93,0x58,0x36,0x78,0x7a,0x71,0x64,0xb4,0xf4, + 0x54,0x23,0xb5,0x36,0xb1,0xd6,0x98,0x92,0x20,0xea,0xcc,0x74,0x86,0x7a,0xbd,0xc9, + 0x4b,0xee,0xc4,0x27,0x13,0xbc,0xa8,0xc5,0x60,0x5e,0x8f,0x82,0x8e,0x34,0x92,0x13, + 0x90,0xbb,0x19,0xb7,0xf0,0xc9,0x25,0x93,0xa0,0x28,0x62,0xc4,0x52,0xd6,0x93,0x3a, + 0xd7,0x08,0x3b,0xbd,0x99,0x07,0xae,0xd9,0x10,0x51,0x52,0x53,0x1b,0x72,0xbb,0x7e, + 0xa9,0x61,0x4d,0x6c,0x0d,0x08,0x1f,0x48,0x2d,0x16,0x21,0x5e,0x65,0x7d,0x3d,0x7a, + 0xd0,0x01,0x2b,0x1e,0xff,0x30,0x16,0xdb,0xfa,0x15,0x02,0x29,0xfb,0x0b,0x31,0xb4, + 0x4b,0xc4,0xf6,0xfb,0x46,0xb0,0x8f,0x51,0x19,0x16,0xf4,0x99,0x74,0xf6,0xfe,0xf8, + 0x2e,0xa3,0xbe,0x4e,0x3f,0x35,0x2e,0x6a,0x48,0x29,0xee,0x13,0x83,0xdd,0x35,0xfc, + 0xc2,0xd7,0xae,0x98,0x6c,0xbd,0x66,0x28,0xd4,0x52,0x05,0xec,0x18,0x69,0x06,0xaf, + 0xc8,0x1e,0xfd,0x2f,0x16,0x31,0x6f,0xb9,0xaa,0x51,0xef,0xdc,0x5b,0xc1,0x11,0x3b, + 0xaf,0x9a,0xb7,0xfa,0x1a,0xb7,0x3f,0x59,0xe9,0xd4,0xc8,0x79,0xdb,0xe5,0x94,0x60, + 0x89,0x76,0xc5,0xc6,0xb7,0xbb,0x0e,0x1a,0xc9,0x46,0xe9,0x2d,0xb1,0x91,0xd3,0x96, + 0x26,0x92,0x97,0xf4,0x95,0xc3,0x2f,0x52,0x0d,0xaf,0x2d,0x48,0xf6,0x91,0xde,0x79, + 0x4e,0x8d,0xb6,0x83,0x97,0xe3,0x33,0x63,0x0b,0x6f,0xa3,0xe7,0xd2,0xe8,0x70,0x34, + 0x20,0xc1,0xf0,0x2f,0x93,0xa9,0x5b,0x23,0xc4,0xf3,0x99,0xb9,0xe6,0x72,0x19,0x33, + 0x53,0x92,0xba,0xdf,0xb5,0xa2,0x22,0xfd,0xb1,0x85,0x88,0x14,0xa9,0xa6,0x00,0x6f, + 0xec,0xc1,0x13,0xb4,0xb6,0x2f,0x79,0x94,0x63,0xb9,0x78,0x97,0x5a,0xe3,0xf1,0xe6, + 0x71,0x0d,0x69,0x82,0x37,0x2c,0x4b,0x8b,0x78,0x89,0xad,0xd2,0x37,0x19,0x33,0xd8, + 0xf1,0x28,0x96,0xb5,0x15,0xef,0xc6,0x3c,0x52,0x1a,0x0f,0xb1,0x76,0x65,0x2d,0x4f, + 0xad,0x17,0x32,0x75,0xbf,0xb3,0x08,0xc2,0xbc,0x87,0x0a,0x69,0x52,0xee,0x11,0x84, + 0x0e,0x29,0xca,0x95,0x1e,0xa6,0xaa,0xd2,0xb5,0x84,0xbe,0x51,0xd0,0xf2,0x97,0x69, + 0x01,0x7c,0xb4,0x69,0x11,0xc8,0x32,0x58,0xb4,0x85,0xd6,0xef,0x7f,0x91,0xeb,0x62, + 0x19,0xc5,0xa1,0x1d,0x3e,0xad,0xc4,0xfc,0x0f,0x4b,0x9e,0xa9,0xde,0x59,0xc6,0x6e, + 0xe7,0x3d,0x28,0x3c,0xbd,0xaa,0xdb,0x4e,0xc3,0x61,0x8a,0x9e,0xf3,0x5d,0x14,0x5c, + 0xee,0x0e,0x62,0xab,0x7c,0xdc,0xe5,0xe8,0x4f,0x8c,0x01,0x8e,0xf2,0x1c,0x75,0x29, + 0xee,0x88,0x6b,0x83,0x3d,0xa8,0x2b,0xf9,0x86,0x63,0x33,0x4f,0xdc,0xe3,0x0e,0xa8, + 0x03,0xce,0x93,0xdd,0xbe,0x5e,0x45,0xd3,0x42,0xad,0x3b,0x5f,0xdd,0xe2,0xe2,0x73, + 0x5c,0x30,0xb7,0x02,0x37,0xcb,0x24,0xd5,0x68,0x9d,0x53,0x59,0x95,0x76,0xff,0x16, + 0x7c,0x24,0xe4,0xbb,0xb5,0x71,0x84,0x4d,0xea,0x57,0x10,0xd0,0xab,0x2c,0x7c,0x1c, + 0x01,0x99,0xb5,0x06,0xfc,0x39,0x37,0x45,0xd7,0x47,0xb5,0x59,0xc7,0x79,0x95,0xd4, + 0x67,0x11,0xf4,0x9c,0x50,0xc2,0xbd,0xf3,0xa5,0x2e,0xa7,0xb5,0x1e,0xfc,0xd7,0x20, + 0x02,0xda,0x64,0x24,0xb4,0xfc,0xf3,0x00,0xe4,0xd7,0xcc,0x1c,0x70,0xf5,0x35,0xdd, + 0xc0,0xd4,0x8c,0x92,0x0c,0xba,0x76,0xe7,0xc4,0xd3,0xf4,0xe6,0x48,0xd5,0x71,0x05, + 0xca,0x1b,0x3c,0x37,0xbe,0xb9,0xc4,0x81,0xa5,0xd9,0xb8,0x85,0x79,0x60,0xd6,0x35, + 0xb7,0x6a,0x8d,0x93,0xc8,0x3a,0x2d,0x62,0x84,0xf7,0xdd,0xf3,0xc8,0xf7,0x2e,0x3b, + 0xa9,0x1b,0xb4,0x4e,0x3a,0xb2,0x3c,0xa8,0xcb,0x99,0xf7,0xc8,0x1d,0xfc,0x70,0xa3, + 0x69,0x14,0xbc,0x9f,0xc6,0x34,0x40,0xef,0x5e,0x0b,0x62,0xd8,0x8a,0xe9,0x1d,0x6d, + 0x2c,0x6b,0x32,0xf1,0x1f,0x87,0x6e,0xa0,0x09,0x65,0xd1,0x4d,0xd8,0xe1,0x51,0xa3, + 0xce,0xc9,0x7b,0x65,0x54,0x71,0x87,0x41,0x14,0xb7,0x07,0x40,0x70,0x56,0x9e,0x22, + 0x88,0x41,0x9e,0x4c,0x3b,0x67,0x0e,0x68,0x4c,0xbe,0x4d,0x3e,0x76,0x85,0xfe,0xa8, + 0x47,0x96,0xce,0xbc,0x7c,0x43,0x2e,0xe2,0x0c,0xbd,0xb3,0x84,0xdc,0x0d,0x9f,0xc3, + 0x53,0xd1,0xe5,0x2d,0x3c,0xf6,0x2d,0xfe,0x4d,0xd8,0xef,0xfe,0xf8,0xff,0x11,0x3b, + 0xcc,0xbf,0x97,0x5d,0xd1,0xdc,0x07,0x79,0xea,0x25,0xf8,0x21,0x60,0xbe,0x3a,0xe8, + 0x52,0x4f,0xf3,0x42,0x16,0x1b,0xc9,0x96,0x7b,0xf2,0xe8,0xa6,0x51,0xe7,0xfe,0x7c, + 0xa0,0x6d,0x29,0x82,0x12,0x61,0x1f,0x89,0xa0,0xee,0x34,0xab,0xae,0xfc,0x51,0x18, + 0xd0,0x04,0xa0,0x72,0x1d,0x39,0xd1,0xa1,0x30,0x41,0xa9,0xdf,0x7c,0x6f,0x6b,0x80, + 0x80,0x63,0x9d,0xb7,0xb3,0x13,0x8e,0xd9,0x83,0x0e,0x7a,0xcb,0x2c,0x78,0x11,0x33, + 0x2c,0x85,0xb8,0x02,0x72,0x66,0xfc,0x13,0x28,0xe2,0xae,0xc5,0xb9,0x27,0x98,0xaa, + 0x68,0x0d,0xd8,0x61,0x1c,0x26,0x8a,0xb0,0x07,0xce,0x82,0x26,0x6b,0x27,0xc1,0xba, + 0x63,0xa5,0x12,0xe3,0x93,0x6c,0x87,0x12,0xa0,0xe0,0xaf,0xc0,0x33,0x59,0x49,0x42, + 0xf7,0x2f,0x5b,0x71,0xa0,0xf3,0xa6,0x82,0xa1,0xe8,0xc9,0x3c,0x72,0x6e,0x58,0x09, + 0xaf,0x0b,0xc6,0x88,0x18,0xea,0xed,0x5b,0x34,0x24,0x12,0x72,0xd5,0x0a,0x18,0xe3, + 0xf6,0x65,0xda,0x15,0xba,0x32,0x52,0x9d,0xb6,0x25,0x65,0xbe,0x58,0xee,0x45,0xd5, + 0x61,0xa3,0xda,0x9c,0x3d,0x2c,0xf4,0xe9,0xd5,0x08,0x38,0xa8,0x4b,0x55,0xcf,0x28, + 0x28,0xaa,0x49,0x7b,0x1b,0x28,0x79,0xa8,0xca,0x8b,0x20,0xdf,0x75,0x96,0xf7,0xe9, + 0xbe,0x0f,0x78,0xbd,0xb9,0x4c,0x04,0x56,0x28,0xb9,0x85,0xe8,0x7a,0xdb,0x8a,0x85, + 0x78,0xa0,0x26,0x33,0xc5,0xa6,0xf2,0x5d,0xce,0x7c,0x22,0x55,0x5d,0x6c,0xf4,0xec, + 0x7e,0x4d,0xf1,0x0a,0x94,0xd1,0x05,0x4d,0x4f,0x6f,0xeb,0x8d,0xb4,0xe5,0xd8,0xdd, + 0xfd,0x95,0xeb,0xb7,0xae,0x39,0xb3,0x49,0x49,0x4b,0x9b,0x1f,0xf8,0xbe,0x97,0x50, + 0x28,0xef,0x48,0xe6,0x71,0x10,0xb0,0xdf,0xc3,0xf0,0xaa,0x70,0x32,0xdf,0x47,0xa1, + 0x5d,0x53,0xb4,0xc4,0x33,0x3e,0x62,0x8d,0x52,0xd3,0xe2,0x89,0x98,0xbb,0xba,0x91, + 0x1f,0x99,0xfd,0x07,0xb9,0x56,0x82,0xa3,0x25,0xdf,0x06,0xd6,0xbb,0xf0,0x45,0x74, + 0x1c,0x1c,0xed,0xd5,0xbf,0x3e,0xa5,0x4e,0x08,0xa2,0xc3,0x57,0xf5,0xf6,0x3c,0x68, + 0xc9,0x27,0x83,0x40,0x44,0x80,0xd0,0x64,0x37,0x5e,0x6b,0x77,0x5c,0xa9,0x8c,0x6c, + 0xd1,0xee,0x77,0x14,0x3d,0x59,0x58,0x83,0x1e,0xd3,0x7f,0x50,0xaf,0x16,0x1e,0xfa, + 0xd9,0xce,0x9f,0xc7,0xb4,0x85,0xb9,0x92,0xc1,0xd0,0xb3,0x41,0xf1,0xb6,0x27,0x2d, + 0x7d,0x55,0xf3,0xa8,0x71,0x17,0x5d,0x31,0xe7,0x7e,0xf8,0xc8,0xeb,0x40,0x38,0xb5, + 0x40,0xb1,0x8c,0x88,0x9b,0x35,0xba,0x37,0x6b,0x88,0x03,0x57,0x91,0x77,0xd2,0xf7, + 0x8a,0xec,0x84,0xbc,0x9a,0x34,0x56,0x7d,0x82,0x3d,0xb8,0x68,0xda,0xfc,0x15,0x51, + 0xae,0x10,0x8d,0x9d,0x1b,0x37,0xd7,0x69,0xc6,0x18,0x46,0x57,0x11,0x8b,0x9c,0xa7, + 0xd1,0xae,0x85,0xdd,0x1a,0x3d,0xa0,0x5b,0xa1,0xaa,0xb9,0x5f,0xf8,0xd4,0x13,0xc8, + 0xfe,0x9f,0xce,0xd4,0x3c,0xef,0x9d,0x2e,0x42,0x47,0x51,0x5a,0x93,0x5f,0x9c,0xcb, + 0x41,0xfe,0xee,0xcc,0x08,0x49,0x07,0xbb,0xce,0x02,0x8e,0x0e,0x5a,0xb4,0xe0,0x78, + 0x62,0x9d,0x5b,0x49,0xcc,0x9a,0xf4,0x9f,0x15,0xe1,0xad,0x0d,0xf6,0xd3,0x8f,0x65, + 0x59,0xbe,0x15,0xdc,0x36,0x92,0x5e,0x9f,0x54,0xe9,0x33,0x8e,0xd1,0xf9,0x18,0x32, + 0x9e,0x2f,0x27,0xe4,0x93,0xa0,0x8f,0xa6,0x47,0xaa,0xc8,0xa4,0x55,0x07,0x56,0x15, + 0x03,0x83,0xec,0xf0,0x97,0xe9,0xec,0xcd,0xc8,0x47,0xc7,0xc9,0x53,0xa8,0x81,0x71, + 0xe6,0xd3,0x09,0x03,0x75,0xb9,0x11,0xaa,0xc2,0xc8,0xeb,0x26,0x77,0x6f,0xa7,0x0c, + 0xf1,0x57,0x63,0xe7,0x99,0xac,0xac,0xf3,0x87,0x3e,0xaf,0x71,0x93,0xa2,0x76,0xe3, + 0xed,0xa7,0xe8,0x42,0x96,0x67,0x7a,0x00,0x05,0x33,0xdf,0x0d,0x8f,0x11,0x38,0xd6, + 0x71,0xdf,0x8a,0x52,0x14,0xe6,0x64,0x0a,0x41,0x9f,0x54,0x09,0x9d,0xc6,0xda,0xf2, + 0xa4,0x29,0xb8,0x48,0x73,0xca,0x09,0x43,0x92,0x86,0xe2,0xe3,0x9d,0xd5,0x7f,0xf6, + 0x6c,0xe4,0x33,0x53,0x17,0x76,0x99,0xf7,0x8e,0xe7,0x42,0xe4,0xf5,0xed,0x35,0x11, + 0x7c,0x1c,0xc2,0x4a,0x0b,0xa7,0x28,0x2f,0xb3,0x1d,0x8c,0x5e,0x7f,0x88,0x14,0x27, + 0x80,0x2f,0x75,0xfc,0xb1,0x22,0xee,0x06,0xa6,0x8d,0x27,0x0d,0xd8,0xa9,0xb6,0x79, + 0x67,0x7b,0xc3,0x4b,0xbd,0x21,0x67,0x3a,0xe6,0x41,0x73,0x47,0x11,0xa8,0x35,0xdb, + 0xe7,0x26,0x54,0xfd,0x1f,0xe3,0x01,0x8b,0x2b,0x64,0x2b,0xbb,0xab,0x9e,0xd9,0xfb, + 0x28,0x23,0xbb,0x50,0xfb,0x53,0x2b,0x71,0xab,0xa0,0x70,0x70,0x7c,0x18,0x40,0x29, + 0x7b,0x29,0x57,0xc5,0x7c,0xa9,0x2a,0x4b,0x57,0xcc,0xc7,0x25,0xa3,0x5c,0xb3,0xda, + 0xf6,0x8a,0x4f,0xca,0x65,0xc2,0x11,0x6e,0xcd,0x5e,0xa7,0x64,0xaa,0x52,0xfc,0xb9, + 0x6f,0x2b,0x92,0x33,0x0d,0xa5,0xed,0x6f,0xef,0x0f,0x3b,0xae,0xe5,0x83,0x37,0xb8, + 0x18,0x8b,0x2c,0x85,0x95,0x38,0x14,0xc8,0x40,0xd1,0xb8,0xf9,0xc9,0x0c,0x8b,0xae, + 0xf1,0x20,0x8c,0xf4,0x74,0xb5,0x65,0x87,0xc0,0xd8,0xd6,0x5a,0xab,0xb3,0x21,0x07, + 0xa6,0xa2,0xa1,0x65,0x36,0xfa,0xb5,0xa7,0xcc,0x45,0x1e,0xc9,0x21,0x89,0x0a,0xab, + 0x75,0xe2,0xd5,0x7f,0xb3,0xfe,0xbd,0x92,0x17,0xd0,0x72,0x4f,0x9e,0xf0,0x5c,0x3d, + 0x93,0xd6,0x7b,0x54,0x3e,0xbc,0x2e,0xe0,0xd5,0x89,0xe4,0x95,0x54,0x72,0x33,0x8e, + 0xaa,0x38,0xf4,0xd2,0xb0,0xd4,0xbd,0x8d,0xea,0xb7,0x28,0x64,0x57,0x58,0xb6,0x48, + 0xd5,0x23,0xe3,0x2f,0x2a,0x7b,0x6f,0xe1,0x74,0xdc,0xf1,0x27,0xe9,0x5b,0x38,0x5c, + 0x18,0x3a,0x7d,0xc8,0x8b,0xf5,0x82,0x34,0x5a,0x21,0x2d,0x65,0xff,0xfd,0x20,0xb7, + 0xac,0x14,0xbc,0x8f,0x1f,0x8b,0xf6,0x2b,0xee,0x24,0x51,0x5f,0x56,0x76,0x7a,0x64, + 0x52,0x08,0x55,0xb9,0x9c,0x46,0xba,0x7d,0xed,0xf9,0x6a,0x6c,0xb5,0x08,0x1d,0x78, + 0x8e,0x35,0xc7,0xcf,0x3d,0xb7,0x4f,0xc9,0x0e,0xba,0xe9,0x0b,0x22,0x51,0x70,0x64, + 0x92,0xbb,0xcf,0xdf,0x53,0x36,0x93,0xfb,0xe9,0xfa,0xa8,0xcc,0x85,0xf2,0x37,0x44, + 0x99,0xde,0x2d,0xe5,0xbc,0x4a,0xcf,0x9a,0xee,0xca,0xba,0x1f,0xdd,0xbc,0x38,0x29, + 0x45,0x40,0x5a,0xbc,0xd4,0x0c,0x5e,0xef,0xed,0xd9,0xfa,0x7a,0x5f,0x5c,0x32,0xcb, + 0x53,0x3f,0x8d,0xad,0x55,0x2f,0x7f,0xfb,0x69,0xef,0xc9,0xd6,0x7c,0xfb,0x39,0x6b, + 0x44,0x1c,0xb5,0x20,0x54,0xbc,0x75,0x99,0xae,0xd7,0xe9,0x5e,0x00,0x52,0x50,0xbc, + 0xf7,0xab,0x10,0x76,0xfb,0x91,0xe8,0x23,0xf3,0x02,0xae,0x84,0xf7,0xcd,0xc8,0x30, + 0x7b,0x0c,0x70,0x1c,0xb6,0xfa,0x70,0xc3,0xcd,0x4c,0x0b,0x46,0x3b,0xd0,0x79,0x05, + 0x69,0x93,0xff,0x39,0xa3,0x0e,0x9b,0x3e,0xc6,0x8a,0x82,0x14,0xa4,0xcd,0x72,0x36, + 0x20,0xa2,0xec,0xe8,0x13,0x58,0x67,0x19,0x6d,0x4e,0xe7,0x0c,0x99,0x12,0x1a,0xf2, + 0x7a,0xab,0xf8,0xbe,0xbe,0x29,0x22,0x44,0xfb,0xef,0x6f,0x34,0x73,0x2b,0x36,0x57, + 0xa2,0x5a,0x73,0xb6,0xbf,0xd8,0x4f,0x83,0xc7,0xc8,0xb8,0xc2,0xc4,0x27,0xe1,0x33, + 0xe0,0x61,0xbe,0x61,0x79,0x42,0x29,0x75,0x22,0xc7,0xb1,0x67,0x44,0x6b,0x72,0x61, + 0x8f,0xf8,0xb1,0x71,0x78,0x43,0x0b,0xc2,0xe7,0x7a,0xd6,0xbc,0x51,0x63,0xd6,0xf3, + 0xe1,0x4b,0x8a,0xe2,0xe3,0x6a,0x6c,0x01,0x90,0x0c,0xb2,0x1f,0x2f,0x5e,0xed,0x62, + 0xdf,0x01,0xd5,0xde,0x2a,0xa5,0xae,0x5a,0xaa,0x42,0xc1,0x3c,0x5f,0x80,0x50,0xf3, + 0x07,0xb7,0x9e,0xc1,0xeb,0x1c,0x30,0x2e,0x69,0x15,0x4c,0xaf,0x20,0xc0,0x0c,0x0a, + 0xf1,0x18,0x33,0xee,0x98,0x3b,0x9b,0x57,0x2a,0x40,0x93,0x22,0xbb,0xbf,0x7f,0x8f, + 0xd4,0x04,0x6e,0x3f,0x9e,0x9a,0x44,0x0a,0x2a,0xdf,0x37,0x0e,0xd8,0xab,0xb1,0x22, + 0x84,0xdb,0xb4,0x5b,0xba,0x82,0xae,0x8b,0xc7,0x40,0xe0,0x83,0xa6,0xf6,0x46,0x27, + 0xea,0x6e,0xfd,0x4a,0x48,0x6f,0x2d,0x6f,0x2b,0xcd,0xb8,0xe9,0x83,0x54,0x03,0x45, + 0x32,0x8e,0x5e,0x7a,0x3a,0x80,0xa0,0x5e,0x6a,0xb0,0xdb,0x90,0xd3,0xee,0x00,0x62, + 0x04,0x9d,0x92,0xe6,0xcf,0x9d,0x4e,0x71,0x58,0x4f,0x29,0x44,0x5c,0xdb,0x3b,0x96, + 0xd2,0x53,0xb2,0xac,0x8e,0x6a,0x09,0x5a,0x98,0x1e,0x8c,0x90,0x42,0x91,0x78,0x05, + 0xe5,0xb9,0x92,0x01,0xc6,0x04,0xad,0x5a,0x83,0x26,0xed,0xa1,0x0d,0x30,0x87,0x97, + 0x5d,0x57,0x8d,0x6c,0x41,0xa8,0x47,0x2d,0xd9,0x11,0x36,0xf2,0xff,0xaf,0xe8,0x45, + 0xb1,0x8b,0x14,0xb6,0x01,0x31,0xf0,0xc4,0x28,0xb5,0xc4,0x41,0x32,0xf9,0x5c,0xa6, + 0x67,0xe9,0xac,0xd6,0x66,0x38,0x02,0x12,0x67,0xf8,0x92,0x87,0x38,0xd1,0xba,0x61, + 0xd2,0xe6,0x3d,0x41,0x91,0xb4,0x72,0xe7,0x32,0x32,0x8c,0x6a,0x55,0xd4,0x47,0x91, + 0x7e,0x13,0x09,0x53,0xd9,0x36,0xcb,0xf5,0xe1,0x52,0x17,0x17,0x13,0xf6,0x78,0xa4, + 0xf4,0x69,0xb3,0x08,0x02,0x38,0x9c,0x76,0x89,0x57,0x52,0x66,0xc3,0x47,0xb6,0x78, + 0x19,0xad,0xdc,0xe2,0x9a,0x5c,0xa5,0x5a,0xc5,0xa4,0x8e,0xba,0xd8,0xe6,0x5d,0x58, + 0x90,0x05,0xb9,0xa0,0xbe,0xe9,0x2a,0x2d,0xad,0x6f,0xcd,0x45,0x80,0x38,0xaf,0x83, + 0x25,0x16,0x30,0x7f,0x50,0xaa,0x67,0xd2,0xef,0x93,0xc5,0x8e,0x81,0xd4,0xc7,0x97, + 0x6b,0x9c,0x90,0xc8,0x93,0x82,0x6b,0xd9,0xcb,0xdd,0xc7,0x1f,0xfe,0xf7,0x04,0x67, + 0xf6,0xc1,0x97,0x47,0x9c,0x58,0x0c,0x5f,0x4f,0xd6,0x7e,0x0f,0x46,0x89,0xe8,0xcb, + 0xea,0xe2,0xa7,0xcf,0x28,0x33,0x9e,0x1a,0x6e,0xd3,0xe2,0x5c,0x59,0x8b,0xf2,0x87, + 0x56,0x03,0xf7,0x35,0x2d,0x70,0x9c,0xd5,0x00,0x1b,0xc4,0xd9,0x06,0xa7,0x95,0x3e, + 0xfc,0xa3,0x18,0xf5,0x1d,0xdb,0x3d,0xd3,0x28,0xa0,0x64,0x3d,0x72,0x74,0x08,0x1f, + 0xcd,0x10,0xc2,0xea,0xcb,0xe3,0x40,0x15,0xb8,0xce,0xf1,0xb2,0x23,0x94,0x12,0xa3, + 0x78,0x13,0xcb,0xeb,0x4a,0x59,0xf1,0x77,0x41,0x1f,0xe5,0x19,0x9b,0x17,0x78,0x3c, + 0xf9,0x36,0x66,0xef,0x7c,0x69,0x1f,0x1e,0x41,0x67,0x83,0xdc,0x66,0x16,0xe4,0xbc, + 0xf7,0xea,0xf3,0x62,0xb7,0x3b,0xe0,0x71,0x3a,0x80,0x14,0x8d,0xa7,0x67,0x84,0xcd, + 0x06,0x05,0xd3,0xea,0xe0,0xe4,0xc1,0x43,0xe6,0x44,0x49,0x8d,0x14,0x05,0x82,0x03, + 0x9e,0xdb,0x55,0x25,0xea,0x59,0x57,0x5f,0x4a,0x87,0xd1,0x89,0xd0,0x56,0x81,0x6b, + 0x07,0xc7,0x32,0x57,0xe8,0x37,0x6e,0x80,0x43,0x4a,0xe1,0x63,0x2e,0x68,0xf6,0x30, + 0x2a,0x7d,0xb0,0xf0,0xf7,0x39,0xa3,0x2d,0x4a,0x00,0xe0,0x10,0x72,0xaa,0x70,0xfc, + 0x65,0xf8,0x3f,0x59,0xd7,0x03,0x8e,0x49,0x75,0xc6,0x01,0xd8,0x4d,0x14,0x34,0x8f, + 0xc3,0xc0,0x99,0xfc,0xa0,0x07,0x1a,0x58,0xfc,0xc5,0x34,0x5b,0xef,0x5d,0xeb,0x3b, + 0x8f,0x00,0xe3,0xcf,0x74,0x7a,0x05,0x0e,0xee,0x46,0x43,0x1b,0x01,0x5a,0xca,0x72, + 0x6d,0xe0,0xbd,0x4e,0x21,0x73,0x20,0xdd,0xa5,0xa8,0xea,0x6a,0xd9,0x8f,0x52,0xa5, + 0x9e,0xf0,0x2a,0xde,0xef,0xe1,0x68,0x37,0xa4,0x89,0xf5,0x65,0xa6,0xe2,0x74,0xcf, + 0xae,0x65,0x3a,0xf1,0xa5,0x2b,0xe3,0x05,0xa6,0xc3,0xa9,0xe3,0xa2,0xac,0x42,0x53, + 0x0f,0xcf,0xb9,0x19,0xb1,0xe3,0x41,0xcb,0x21,0x60,0x7c,0xc0,0x9f,0xb1,0xdf,0xa5, + 0x85,0x1f,0xdb,0x7e,0x34,0xcb,0xc6,0xd1,0x54,0xdf,0x14,0xd4,0x16,0x97,0x74,0x96, + 0xad,0x8e,0x73,0xac,0x42,0x84,0x1c,0xae,0x63,0xe9,0x7c,0x97,0x5a,0xb3,0x7d,0x87, + 0x51,0x1d,0x32,0x76,0xc6,0x11,0x81,0xd0,0xdc,0xdd,0x95,0x83,0x1d,0x43,0x73,0xa6, + 0xa9,0xd1,0x6d,0xf2,0x1d,0xdf,0x76,0x88,0xd9,0x46,0xad,0x86,0xc6,0x13,0xdf,0x88, + 0x36,0x90,0x84,0xc4,0xf8,0xb9,0x4e,0x52,0x88,0x7b,0xac,0xf7,0x2a,0x03,0x17,0x2d, + 0x44,0xf9,0xd4,0x84,0x74,0x45,0xdd,0xf5,0xcb,0xb0,0xf7,0x16,0x3f,0x45,0xe5,0x84, + 0x88,0x88,0xaf,0xda,0xa6,0xf9,0xd1,0xc7,0x7a,0x92,0xf5,0xe6,0xa2,0x4b,0x7a,0x57, + 0x87,0x7c,0xb3,0x35,0xa3,0x32,0x45,0x0d,0x4b,0xda,0x8a,0xf7,0xff,0x67,0xac,0xcc, + 0x4f,0x67,0xff,0xc8,0x99,0x1e,0xa7,0x95,0x54,0x0d,0x1d,0xe9,0x72,0x24,0xb8,0x7a, + 0xce,0x12,0xf9,0xe4,0x3e,0x59,0x3b,0xd1,0x0c,0x29,0xe4,0xa9,0x05,0xbb,0x5f,0xac, + 0x0f,0x37,0xf7,0xfc,0xc0,0xf8,0x26,0x2f,0xf5,0x40,0x73,0x65,0x47,0xc5,0x8a,0xb2, + 0x1e,0x16,0x91,0xa2,0x1a,0xab,0x27,0xbf,0x65,0x73,0xaf,0xa4,0x5c,0x64,0xd9,0x28, + 0x8a,0x0d,0xbf,0x51,0x99,0xba,0xe6,0x1a,0x25,0x8d,0x36,0xf7,0xb5,0x92,0xec,0xe8, + 0x4f,0xf3,0xda,0x38,0x9a,0x42,0x30,0xd6,0xdc,0x90,0x9c,0xfe,0x7e,0x9d,0xf7,0xa0, + 0xc5,0x91,0xc7,0x55,0x1f,0xa5,0x0e,0x94,0x49,0x55,0x48,0x7d,0x01,0x23,0x11,0xdd, + 0x4e,0x1c,0xa5,0x3d,0x9c,0x3f,0x80,0xdf,0x43,0xba,0x20,0x00,0xdb,0xbe,0xa7,0x38, + 0xd8,0xb1,0xbf,0x5b,0xc5,0xbd,0x68,0xa4,0x4b,0x23,0xd8,0xbd,0x56,0xa8,0x44,0x9d, + 0xa0,0xae,0x46,0x90,0x3c,0xa0,0x31,0x46,0xb6,0xbc,0xa0,0xcb,0xdc,0xc7,0x5b,0x1d, + 0xfc,0x40,0x2a,0x2a,0x83,0x77,0x29,0xde,0x51,0x3f,0xa5,0x47,0x27,0x07,0x5d,0xe0, + 0xfd,0xf3,0x99,0x08,0x9d,0x61,0xb5,0xaf,0xc2,0xe3,0x8e,0x4b,0x1b,0xf2,0xca,0x63, + 0xf7,0x0b,0x68,0x49,0x97,0x24,0x28,0x1d,0x61,0x55,0xc0,0x91,0xb3,0x6b,0xef,0x78, + 0x60,0x4a,0x37,0xb6,0x91,0xa2,0x66,0x58,0x45,0x44,0x92,0x96,0x72,0x8f,0xf5,0x3e, + 0x21,0x47,0xa1,0xf7,0xa3,0xad,0x91,0x41,0x94,0xb9,0xcd,0x02,0x3b,0x77,0xde,0xd5, + 0xa3,0x05,0xd0,0x37,0x71,0xd8,0x3f,0xf5,0xe3,0x6d,0x6e,0x40,0xd5,0xbd,0x62,0xbe, + 0xcc,0x05,0x99,0x4c,0x6f,0x1d,0xb8,0x57,0x8d,0x1c,0xda,0x31,0x5e,0xa0,0x88,0x9a, + 0xe3,0x7d,0x3b,0xc9,0xf8,0x96,0x1e,0x11,0x4f,0x63,0x36,0x43,0x83,0xb4,0x41,0x78, + 0xf8,0x01,0x5c,0x25,0x24,0x30,0x43,0x38,0xbc,0x1a,0xa7,0xa9,0x9d,0xb5,0x33,0xea, + 0xf5,0x67,0x4b,0x74,0x8e,0x69,0xc8,0x5b,0x36,0x57,0xf8,0xfd,0xdd,0x6f,0x7a,0xbb, + 0x32,0x4e,0x43,0xc8,0x7c,0x69,0x92,0x48,0x22,0xb3,0xe7,0x23,0xa7,0x10,0xe7,0x2a, + 0xbc,0x50,0xb2,0x5e,0xe6,0x2b,0x2e,0xfc,0x6b,0x48,0xca,0xdd,0x38,0x92,0x88,0x62, + 0x17,0xf3,0xa3,0xff,0xab,0xd3,0x6d,0x41,0xcc,0x4f,0x89,0xf0,0xe6,0x2c,0xe7,0xca, + 0xb3,0x05,0xb9,0x35,0x3a,0x29,0x01,0x90,0xf7,0x0d,0xa3,0x8d,0x78,0xce,0xbd,0xc7, + 0xfa,0x18,0xdd,0x70,0xd7,0x72,0xcf,0xa3,0x1f,0x5c,0x45,0x5a,0x8d,0x01,0x55,0xbc, + 0x84,0xe0,0xaa,0x10,0x70,0x59,0x3a,0x65,0x60,0xf5,0xe2,0x14,0x77,0xb9,0x80,0xa1, + 0xe2,0x02,0x07,0xe8,0xb6,0x38,0xcc,0x97,0xdf,0x43,0xeb,0x04,0x05,0x21,0xf2,0xe3, + 0xd7,0xcc,0x4d,0xb0,0xbf,0x71,0x54,0xf0,0x9a,0x5f,0xa9,0xd7,0x02,0x16,0x64,0x0b, + 0xc3,0x4b,0x7c,0x83,0xf0,0x64,0x6c,0x30,0x99,0x5b,0x14,0xc4,0x1a,0x8b,0x04,0xa1, + 0x40,0x9b,0xae,0x50,0x10,0x9a,0x56,0xf4,0xc0,0xae,0xa8,0x70,0x53,0xb8,0xfc,0x86, + 0x68,0x27,0xcd,0x23,0xb4,0x1d,0x35,0xa0,0x1b,0x5b,0xeb,0xd0,0xf4,0x77,0xdc,0x55, + 0x83,0x15,0x0d,0x34,0x41,0x75,0x8d,0x75,0x9e,0xd1,0xd5,0xed,0x88,0x57,0x2d,0xf7, + 0xf9,0xc5,0x9c,0x1a,0x3e,0x71,0x4d,0xbf,0x6e,0xa2,0xae,0x57,0x7e,0x81,0xb7,0xdf, + 0xf3,0x13,0x4e,0xe4,0x2f,0x78,0xde,0xc4,0x77,0x1b,0x33,0xc3,0xe4,0xec,0x1f,0x8d, + 0xdb,0xe5,0xb9,0x09,0x93,0x2f,0x4c,0x09,0xb4,0x3a,0xdb,0xe3,0x0d,0x26,0xcb,0x71, + 0x69,0xd6,0x2c,0xa5,0x65,0x8a,0xd3,0xc5,0x96,0x1b,0x8c,0x86,0x81,0x8e,0x7e,0x39, + 0x89,0x5c,0xc6,0xd8,0x3c,0x2f,0x36,0xac,0x24,0x51,0x61,0xd9,0x7c,0xf5,0x5e,0xe9, + 0xd4,0xb6,0xb0,0xe9,0x58,0xb4,0x66,0x70,0xe9,0x75,0xfe,0xf5,0x18,0x8f,0x27,0xeb, + 0xa2,0x5c,0xc7,0xcf,0x13,0xb3,0xa8,0xae,0xe4,0x5d,0x90,0x05,0xcd,0xbe,0x37,0xdd, + 0x16,0x5d,0xd9,0xe8,0x08,0x72,0xe4,0x9b,0xa8,0xe0,0x4a,0x79,0xdb,0x5c,0x1e,0xa3, + 0x37,0x04,0xb2,0x95,0x96,0xa4,0x8d,0x68,0xa1,0x1f,0xbb,0x55,0x28,0x61,0xbb,0x61, + 0x71,0xed,0x6c,0x93,0x56,0x53,0xf8,0xf3,0x33,0x1c,0xee,0x0a,0x53,0x29,0xc3,0xed, + 0x65,0x2d,0x2a,0x65,0x6b,0xc0,0xdd,0xbc,0xc5,0x62,0xb3,0xd4,0x50,0x6f,0x4f,0x2e, + 0x86,0xda,0xb9,0x75,0xd7,0xe1,0x41,0x0c,0xe7,0x82,0xdc,0xb3,0x90,0xc6,0x74,0xb2, + 0xc5,0xd5,0xc4,0x0a,0xb5,0xa2,0x60,0xc3,0xe7,0x3b,0xe1,0x95,0x66,0x6e,0x97,0x3f, + 0x26,0xe7,0xec,0xb4,0x11,0xfc,0x01,0x0d,0xe0,0x84,0xe8,0xea,0xa8,0x48,0xa1,0x63, + 0x84,0x8b,0xc1,0x17,0x37,0x2e,0x2b,0x6c,0xae,0xd7,0x89,0x87,0xa4,0xa4,0x33,0xce, + 0xfb,0xc5,0x5d,0xd3,0xc0,0xa8,0xf8,0x32,0x86,0x86,0x6f,0x86,0x74,0x27,0x1c,0x33, + 0x64,0x59,0xa6,0xb8,0x2f,0xe3,0x22,0x2b,0x40,0x8a,0x72,0x7a,0xab,0x84,0xd1,0x3d, + 0xac,0x76,0xa2,0x1b,0x3d,0x59,0xe5,0x3b,0x4b,0x20,0x17,0x41,0xc0,0xb6,0xe3,0xca, + 0x94,0x87,0x19,0xc8,0x5e,0xaa,0x2b,0x23,0x49,0xea,0x54,0xd0,0x2d,0x3c,0x72,0x86, + 0x28,0x34,0x68,0xf7,0xa2,0x66,0xe1,0xbf,0xac,0x91,0x84,0x12,0x22,0x76,0x72,0xeb, + 0x6d,0x73,0x3d,0x4f,0x18,0xe5,0xad,0x6a,0x39,0x4c,0xc0,0x5e,0x95,0x43,0x7b,0xde, + 0x2f,0x8f,0xfa,0x5e,0x03,0xef,0x72,0xdd,0x2c,0xed,0x3a,0x5e,0xba,0xe7,0x1b,0xbb, + 0x29,0x2f,0xfd,0xcb,0xeb,0xdc,0xb3,0x17,0xbb,0xc8,0x53,0x1d,0xbc,0x69,0x53,0xcb, + 0x2c,0xdf,0xb3,0x13,0xac,0xbd,0x03,0xf9,0xc6,0x12,0xbf,0xfb,0xff,0xc5,0x07,0x60, + 0xc4,0x6f,0x87,0xba,0xec,0x41,0xf4,0xd7,0x03,0x92,0xe0,0x98,0x56,0xb2,0x77,0x92, + 0x23,0x21,0x57,0xb1,0x94,0x4e,0x8d,0x36,0x46,0xe6,0x5b,0xd8,0xa3,0xf9,0x96,0x61, + 0x5c,0xb1,0x65,0xd3,0x1c,0xbf,0xf4,0x7e,0xe2,0x2b,0x2a,0x66,0x79,0x8f,0x43,0xc9, + 0x58,0x0f,0x41,0x04,0xcd,0x6e,0xe6,0x85,0x9a,0xc2,0x7c,0x33,0xb0,0xd6,0x74,0x7b, + 0x87,0x0b,0x9a,0xee,0x75,0x44,0x0c,0x60,0x6f,0x69,0xca,0xd3,0xd5,0x7f,0x73,0x89, + 0xaa,0x68,0xd2,0xfe,0x74,0x45,0xa3,0x56,0x61,0x2c,0xc2,0xde,0xd0,0x55,0xd1,0xa1, + 0x5d,0xd4,0xfd,0xe7,0xfc,0xa7,0x4d,0xb3,0xe2,0xd9,0xef,0xd6,0x9a,0xe9,0x0f,0xfb, + 0x52,0x11,0xf5,0xc7,0x56,0x08,0x1f,0x77,0xcc,0x51,0x6b,0x84,0x9b,0x9b,0x20,0x2b, + 0x2a,0xb2,0xc0,0xb6,0x3d,0x68,0x6d,0x91,0x17,0x00,0x76,0xfa,0xc9,0x59,0xc2,0x05, + 0x2c,0x39,0x6e,0xca,0xca,0xd7,0xfe,0xdf,0xb2,0x42,0x6d,0xf9,0x73,0x26,0xf3,0xe9, + 0x53,0x07,0x80,0x89,0x6c,0xde,0x82,0x63,0x58,0x30,0xa0,0x50,0x15,0x6b,0xef,0x5a, + 0x83,0x06,0x10,0x04,0x48,0x2d,0x8d,0x42,0xdd,0x27,0x00,0x3a,0x02,0xb9,0x66,0x0a, + 0x14,0x17,0xfa,0x0c,0x5d,0x30,0x56,0x34,0xec,0xf4,0x94,0xf3,0x7d,0xbc,0xd6,0x0a, + 0x8c,0x62,0xe3,0xac,0x9c,0x36,0x06,0x78,0xef,0x55,0x19,0x03,0xbc,0xbf,0x7d,0xfa, + 0x9e,0x81,0xf1,0xfa,0xb8,0xbf,0x48,0x89,0xad,0x61,0xeb,0x23,0xda,0x25,0x36,0x1f, + 0x0a,0x1e,0x43,0xee,0xd3,0xfd,0x47,0xab,0xeb,0xd0,0x64,0xcd,0x88,0x09,0xdf,0xd2, + 0x06,0x28,0x16,0x80,0x30,0x22,0xef,0x07,0xe1,0xbc,0x2f,0x15,0xf1,0xe1,0xf0,0x18, + 0xfc,0x4e,0x80,0x05,0xed,0xc0,0xd8,0xe8,0x6f,0x4b,0xca,0x82,0xba,0x05,0x76,0xe9, + 0x62,0xdf,0xb9,0xc2,0x52,0x02,0xe9,0x29,0x3d,0x0d,0x7a,0xd6,0x54,0xef,0x69,0xa6, + 0x62,0x0e,0x49,0x21,0xc5,0xa8,0x9b,0xd9,0x19,0x88,0x09,0xc6,0x55,0xee,0xd3,0x7f, + 0x7a,0x46,0x55,0xa2,0xb7,0x4a,0xf0,0x13,0x7e,0x97,0x10,0xa5,0x23,0xe5,0x5e,0x6c, + 0x05,0x04,0x60,0xe4,0x20,0xb3,0xe6,0xf5,0xf4,0x20,0x8a,0xfe,0x55,0x9d,0x96,0x6e, + 0xe1,0x6b,0xa3,0x54,0x93,0x9c,0x2f,0x66,0x63,0x03,0x81,0x96,0x56,0xeb,0x09,0x23, + 0x20,0x8c,0x71,0xbd,0x37,0x68,0x61,0xf4,0x7c,0xfa,0x61,0xf1,0xd8,0x87,0xae,0x9a, + 0x0a,0x02,0x7a,0x3d,0x74,0x6a,0x90,0x6e,0x2a,0x09,0xc0,0x9b,0xb3,0x0c,0xbe,0x7a, + 0xba,0x6c,0x0a,0x0d,0xe5,0xc8,0xe2,0x09,0x25,0x0b,0x39,0xcf,0xdd,0xe4,0x57,0x6b, + 0xc8,0x05,0x93,0x8d,0x39,0xad,0x29,0xda,0xa4,0xc1,0x03,0x1c,0x79,0xeb,0x33,0xf2, + 0x25,0x06,0x4b,0x58,0xe0,0x8b,0x0b,0xb9,0x68,0x25,0xc9,0x8b,0x32,0x0f,0x85,0x79, + 0x7e,0x4e,0x02,0x15,0xd0,0xb1,0x44,0x0a,0xb5,0xd1,0xea,0x96,0xf6,0x61,0x32,0x67, + 0x73,0x4f,0x5a,0x37,0x15,0x4f,0xff,0x9a,0x4d,0x9d,0x92,0x74,0x5d,0x47,0x53,0xe8, + 0xe9,0xf1,0xbb,0x6a,0x63,0x21,0x93,0xd5,0xa2,0x13,0x7f,0xf2,0x2b,0xb8,0xd2,0xb6, + 0x62,0xbe,0x81,0xe0,0x24,0x74,0x43,0x02,0x9a,0x44,0x5d,0x03,0x78,0x0a,0x64,0x37, + 0xcb,0x50,0xfa,0x83,0x14,0x91,0x72,0xf9,0x63,0x63,0x04,0xbb,0x4c,0xc4,0x72,0xf2, + 0xd2,0x74,0x2c,0xe6,0x53,0xf6,0x0c,0x11,0xc0,0xf8,0xa2,0xed,0x33,0x8e,0x45,0xe4, + 0x22,0xf5,0xbd,0xb5,0x76,0x9d,0x4f,0x3c,0x9c,0x10,0x86,0xd7,0x1b,0xc3,0x35,0x6a, + 0x0d,0x1e,0xf3,0x92,0x95,0x3e,0x8b,0x51,0xdd,0x11,0xa3,0x8c,0x7c,0x85,0xd1,0x44, + 0x02,0x16,0x28,0x56,0x64,0x3c,0x0d,0xef,0x87,0x38,0x14,0x25,0x41,0x36,0xdf,0xf3, + 0x8e,0xb5,0x60,0xab,0xe9,0xca,0xde,0xf2,0x61,0x17,0x63,0x6f,0x86,0xd3,0x7d,0x51, + 0x01,0xb6,0xd5,0x83,0xd0,0x77,0x37,0xe4,0xe1,0x36,0x56,0x11,0x09,0x18,0x5a,0xf2, + 0x32,0x56,0x76,0x4f,0x44,0x2c,0x8e,0x94,0x6e,0xfa,0xa5,0xb5,0xeb,0x35,0xfd,0xaf, + 0x89,0xe7,0x79,0x64,0xe2,0x75,0x06,0x01,0xc9,0xc7,0xde,0x55,0x1b,0x8a,0x0b,0x1a, + 0xc7,0x56,0x1e,0x67,0xf8,0xb3,0x8f,0x88,0xe8,0x26,0xca,0xde,0x10,0x08,0x5e,0x99, + 0xae,0x18,0x7c,0xf2,0x35,0xec,0xa3,0xcb,0x13,0xf7,0x81,0x94,0xfe,0x7b,0xb4,0x7b, + 0x1e,0x7e,0x08,0x8d,0x1a,0x86,0x25,0x08,0xd1,0x04,0xc7,0xc4,0x10,0xca,0x18,0xe5, + 0xf4,0xb7,0x27,0xaa,0xb7,0x5e,0xc9,0x7a,0x62,0x56,0x9a,0x04,0x8f,0x88,0x70,0x38, + 0x62,0xe4,0x94,0xde,0x88,0xe4,0x9e,0x44,0xa3,0x1d,0xd8,0xa9,0x92,0x95,0x54,0x1b, + 0x2f,0xbf,0xb8,0x8a,0x47,0x88,0xd3,0x6d,0x9c,0x65,0xaf,0x69,0xae,0xab,0x17,0xd1, + 0xad,0x45,0xae,0x1d,0xff,0xb2,0x89,0xca,0xd8,0xea,0x73,0x6f,0xa7,0x77,0xd9,0x25, + 0xa5,0xff,0x36,0x75,0x78,0xcc,0x52,0x23,0x45,0xbb,0x20,0x55,0x25,0x51,0x5a,0x74, + 0xf2,0x91,0x8c,0x81,0x31,0x0c,0x0d,0x2d,0x75,0x83,0xeb,0xc5,0xd9,0xec,0x18,0x41, + 0x25,0x99,0xc3,0x1a,0x97,0xe2,0x86,0x16,0xc2,0x18,0xcf,0x21,0x3d,0x9b,0x91,0xec, + 0x64,0x1c,0xb2,0x2f,0x7e,0xe7,0x29,0x9a,0x64,0x6c,0x29,0xdf,0x41,0xae,0x7e,0x7a, + 0x27,0x44,0xe0,0x81,0xeb,0xd2,0xdf,0xe6,0x30,0x83,0x4f,0x84,0xbf,0xfc,0x30,0xd7, + 0x64,0xa5,0x89,0x96,0x0b,0xd8,0xc2,0x8d,0x49,0x7a,0x86,0x70,0xb6,0x66,0x5f,0x7f, + 0xef,0x17,0xbb,0x45,0x25,0x7f,0x79,0xd2,0xf5,0x12,0xe7,0x05,0xb6,0xec,0xb2,0x53, + 0x37,0xf6,0xfe,0x39,0xe5,0xcb,0xd5,0x9b,0x42,0x8a,0x98,0xf3,0xdc,0x7e,0x5d,0xc8, + 0xad,0x97,0x98,0xbf,0x21,0x07,0x27,0x0d,0xed,0x67,0x4d,0xc6,0xe0,0xa5,0xf9,0xe4, + 0xf4,0xba,0x92,0x2e,0xcb,0x06,0xac,0xbe,0x14,0xe5,0x81,0x4e,0xdd,0xf6,0x9e,0x36, + 0x73,0xd7,0x07,0x2b,0x29,0x0b,0xa2,0x10,0xfc,0x3f,0x24,0xc9,0xf8,0x5c,0x54,0x61, + 0xbf,0x14,0x0b,0x6d,0xff,0x6c,0x01,0xc4,0x30,0xa7,0x02,0x4f,0x5d,0xfd,0x63,0x48, + 0x46,0xe0,0xf8,0x4c,0xdc,0xa8,0x15,0x9a,0xce,0x8e,0xe0,0x8e,0xb5,0xa8,0x03,0xb1, + 0x09,0x8c,0x52,0xb1,0x2c,0x58,0xba,0xc6,0x97,0x8f,0x75,0x18,0x60,0xcd,0xb7,0x15, + 0xa0,0x52,0xab,0xcb,0xad,0xfa,0x24,0x15,0xcd,0xaf,0xc9,0xdf,0x4c,0xac,0x86,0xab, + 0x28,0x2e,0x53,0x72,0x38,0xe2,0x2c,0x99,0xcc,0xbd,0x22,0xcc,0xe4,0x92,0x9b,0x60, + 0x9b,0x96,0xee,0x9b,0x74,0xd5,0xd8,0xd9,0xfa,0x4d,0xb6,0x55,0x00,0x5d,0xb3,0x92, + 0x25,0x91,0xba,0xf4,0xca,0x1c,0xfb,0x8f,0x63,0xd0,0xf4,0xd7,0x16,0x03,0xd3,0x70, + 0xa2,0x90,0xdd,0xa3,0x5d,0xa8,0xd4,0xe3,0xea,0x59,0x26,0xe0,0x3e,0x4a,0x2d,0xe1, + 0x27,0x74,0x63,0x32,0x42,0x4e,0x69,0x43,0x1a,0xdc,0xab,0x8b,0xf3,0xf2,0x84,0x46, + 0x05,0x55,0xbd,0xf8,0x91,0xa4,0xcc,0x82,0x62,0xf9,0xd5,0xc2,0x9d,0x90,0xd4,0x2c, + 0x37,0xd8,0x62,0xc5,0x7a,0xad,0x24,0x1f,0x54,0xbf,0x83,0x72,0x24,0x3b,0x49,0x0c, + 0x95,0x1a,0x1d,0xe3,0x57,0x19,0x6b,0x0b,0xd1,0x1b,0xcd,0x1d,0x5a,0xfb,0x12,0x89, + 0x52,0x0b,0xbd,0xc2,0xf3,0x3c,0xc5,0x13,0x80,0xcc,0x6d,0xc5,0x00,0x56,0x5c,0x68, + 0xa3,0x83,0xb4,0xcc,0x18,0xc5,0x6c,0x4c,0x04,0x39,0xe2,0xcc,0x15,0x89,0x96,0x14, + 0x2c,0x09,0xd5,0xe1,0x45,0x06,0x7c,0x58,0x31,0xdd,0x09,0x87,0x7b,0xd8,0x0f,0xed, + 0x32,0x88,0xd8,0x2a,0x76,0xb7,0xf7,0x8b,0xee,0xd7,0xef,0x6e,0x04,0x2b,0x4f,0x2c, + 0x0a,0x96,0x95,0x27,0x4e,0xfa,0x13,0x4b,0x4a,0x7a,0xa3,0x7f,0xec,0x4e,0x59,0x53, + 0x0d,0xbc,0xee,0xff,0x2f,0x13,0x97,0x8c,0xd5,0x6d,0xe8,0x15,0x9f,0x9f,0x91,0xa0, + 0x01,0x42,0xd6,0xee,0x3d,0x12,0x6e,0x12,0xfb,0x90,0xc5,0x8e,0xff,0xe2,0x24,0xb0, + 0xc6,0x93,0xee,0xbc,0xaf,0x1f,0x4d,0x53,0xcc,0x33,0x8c,0x90,0x73,0x48,0x51,0xe3, + 0xd3,0x30,0x4f,0xad,0xdd,0xa9,0x82,0x13,0x1b,0x92,0xa5,0xfd,0x6d,0xbe,0x12,0xff, + 0xfb,0x8d,0x76,0xc2,0xb1,0x3b,0xa0,0x57,0x4e,0x9f,0xb6,0xc6,0xdc,0x21,0x1f,0xe3, + 0x85,0xdc,0x06,0x25,0xb0,0xa0,0x66,0x69,0xc3,0xa6,0x67,0xd8,0xf1,0x5a,0x53,0xfe, + 0x73,0xff,0xa4,0xe3,0xb4,0x8f,0x81,0xc9,0xff,0x8f,0x51,0x05,0xb1,0xd9,0x5a,0xe2, + 0x0d,0x0e,0xa4,0xe6,0x15,0xae,0xf1,0xd3,0xb6,0x43,0x5e,0xb1,0xf1,0x3a,0x9b,0xcb, + 0x7d,0x0f,0xfe,0x3c,0x6e,0x66,0x0a,0x29,0x3e,0x06,0x89,0xba,0x21,0xa3,0x48,0x22, + 0xf8,0x47,0x0c,0xd1,0x1d,0xaf,0x66,0x48,0xce,0x93,0x01,0xc2,0x68,0xb3,0x7f,0x90, + 0x3d,0x5d,0xce,0x79,0x33,0x19,0x1d,0xa9,0x63,0x99,0x8e,0x64,0xed,0x46,0x54,0x9d, + 0x62,0xf8,0x0e,0xa6,0xb5,0x4b,0x51,0x61,0x9f,0xb0,0x22,0x88,0x81,0x25,0x7d,0xad, + 0xc2,0x05,0xd0,0xbf,0xf3,0x4c,0xcd,0x35,0x33,0x48,0xa8,0xdf,0x34,0xc5,0x31,0xa8, + 0x2f,0xbd,0xb2,0x2c,0x4d,0x86,0x47,0xe9,0x4f,0x4b,0xd2,0x4d,0x3a,0x04,0x78,0x7b, + 0xf0,0xb5,0x13,0x8f,0x7e,0xb8,0xce,0xd7,0xff,0x9d,0x05,0x6a,0x12,0xd2,0xab,0xea, + 0x05,0x86,0x2b,0x6f,0xfb,0xec,0x28,0x4a,0x90,0x40,0x8d,0x08,0xdf,0x6a,0xfd,0x0f, + 0xc0,0xa6,0xff,0xdf,0x3c,0x83,0xd0,0x16,0x29,0xa8,0xd5,0x7e,0xdd,0x2f,0x9e,0xfa, + 0xaa,0x92,0x1d,0xaf,0x35,0x6f,0x62,0xfa,0xad,0xfd,0xea,0x1a,0x1b,0x22,0x0b,0x38, + 0x77,0x4c,0x13,0xc8,0x94,0xa4,0xc4,0xed,0xc1,0xf6,0x13,0x8d,0x98,0x75,0xff,0x3b, + 0x70,0x14,0xc4,0xb8,0x9d,0x97,0x23,0xd9,0x93,0x0d,0x63,0xcf,0x9b,0x8f,0x64,0xc4, + 0x5b,0x9b,0x92,0xbc,0xdb,0x74,0x49,0xbc,0x66,0x71,0x23,0x91,0x76,0xda,0xac,0xe2, + 0x82,0x17,0x28,0xb0,0x52,0xd5,0xdc,0x71,0xa1,0x13,0x0d,0xca,0xbb,0x40,0x85,0x63, + 0x22,0x5a,0xbf,0x35,0x56,0x9d,0xc5,0x25,0xc9,0x17,0xc0,0xe2,0x0d,0xd4,0xdd,0xd5, + 0x02,0x76,0x9a,0x66,0x35,0xbe,0x16,0x23,0xe7,0x49,0xd5,0xa1,0x25,0x42,0x59,0x44, + 0x0c,0xd3,0xcb,0x21,0x8f,0x9b,0x6a,0xd9,0xc5,0x52,0xe7,0x82,0x8d,0xf5,0x4b,0x20, + 0x5e,0xe4,0xb2,0xd3,0xca,0x94,0xdd,0x96,0x94,0x45,0x8c,0x83,0x69,0x6e,0x85,0x71, + 0xb4,0x1e,0x65,0x60,0x78,0x3b,0x05,0xfc,0x41,0x4d,0x2a,0x63,0xa8,0x8b,0x33,0xd7, + 0x42,0x94,0x6d,0x2e,0x42,0x94,0xe5,0x0e,0xe5,0xce,0x11,0x93,0xd0,0xf5,0x7e,0xaf, + 0x0c,0x91,0xd4,0x3a,0xd3,0x5c,0x8c,0x2c,0x1c,0x6d,0x31,0x80,0xe0,0x69,0x08,0x38, + 0x4a,0xab,0xf0,0x9a,0xd8,0xba,0x88,0xbb,0xe9,0x39,0xa0,0x94,0x9a,0x70,0x83,0x76, + 0x5c,0x19,0x17,0x7d,0xa1,0x8b,0xd7,0xd0,0xd5,0x18,0x92,0x06,0xa4,0xb4,0x9c,0x6a, + 0x2d,0x96,0x7d,0x6e,0x35,0x7a,0xdf,0x99,0x88,0xd6,0x0f,0x4d,0xa7,0xda,0x23,0x3b, + 0xa6,0x97,0x62,0x36,0x3c,0x84,0x61,0x6c,0x2c,0x2d,0x8f,0xd7,0xdf,0xfe,0x0c,0x26, + 0xd6,0x71,0x2d,0x9c,0x3d,0x39,0x5f,0x9e,0xe9,0x59,0x61,0xb6,0x6b,0x79,0x43,0x2b, + 0x43,0xb4,0xf3,0x33,0x03,0x50,0x0e,0xe5,0x4f,0xa1,0x28,0x1d,0xf2,0x62,0xac,0x19, + 0xb1,0xe2,0x4d,0xb6,0x34,0x99,0x0f,0xa6,0x48,0x3a,0x5f,0xba,0xd5,0x61,0x58,0x26, + 0xa1,0xec,0xde,0x01,0x30,0x0d,0x74,0xca,0x73,0x0d,0xf0,0x44,0x75,0x0a,0x92,0x22, + 0x06,0x2e,0x90,0x26,0xc5,0x0e,0x80,0xd2,0x09,0xda,0xc6,0x1a,0xbe,0xf0,0xe5,0xf8, + 0xb7,0xb6,0x32,0x36,0x35,0x03,0x69,0x3b,0xf7,0xf6,0xeb,0xd8,0x3f,0xd3,0x89,0x61, + 0xe7,0xb5,0x09,0x65,0xf7,0x04,0x9d,0xd5,0xd5,0x8c,0x83,0xdc,0xb6,0x6f,0xbb,0x34, + 0x8b,0xe6,0xd4,0xad,0x9b,0x02,0x29,0x56,0xe3,0x65,0x30,0xaa,0x6c,0x69,0x60,0x0e, + 0x64,0x8e,0xfb,0x42,0xea,0xc9,0x7a,0x7f,0xbb,0x54,0x69,0x4c,0x6f,0x10,0x8d,0xc7, + 0xe4,0x5c,0x31,0x87,0x9f,0xa5,0x62,0x90,0xbe,0xc5,0xa8,0x45,0x71,0x53,0xfe,0xa0, + 0x03,0x0a,0x8b,0x53,0x94,0x97,0x07,0x4b,0x1b,0x76,0xe8,0x49,0xbb,0xa5,0x5c,0x0d, + 0x28,0x03,0xdc,0x09,0x38,0x23,0x9a,0xb2,0xad,0xd3,0xa7,0xaa,0x7c,0xd0,0x8a,0x68, + 0x6f,0x6e,0x90,0xae,0xed,0x06,0x22,0x1e,0x7e,0xa4,0xaa,0x85,0xfc,0xe2,0xba,0x3a, + 0xf0,0x25,0x79,0x23,0x77,0xee,0xea,0xdd,0x25,0x72,0x8b,0x4f,0x86,0xa8,0x55,0x1c, + 0x2c,0xca,0x0f,0x3b,0xfe,0xe1,0x60,0xa4,0xfa,0x4c,0x7d,0x64,0x64,0x57,0x30,0xc1, + 0xe5,0xe8,0xf2,0x76,0x2a,0x51,0x52,0x6f,0x86,0x5d,0x79,0xb0,0x58,0x96,0x86,0xc8, + 0x0f,0x85,0xf8,0x35,0x90,0x0b,0x69,0x9c,0xcd,0xce,0x3a,0xd3,0xac,0x60,0x39,0x4a, + 0x2d,0x73,0x0f,0xdd,0x82,0xa4,0x64,0x83,0x84,0x63,0x26,0xeb,0xae,0x5c,0x2e,0x24, + 0x89,0x0c,0x3f,0x1f,0xeb,0xed,0x7e,0x99,0xfc,0x0d,0xa2,0x69,0x78,0xf4,0x76,0x34, + 0x00,0x2f,0xfa,0x64,0x68,0x34,0xcb,0x52,0xa5,0x21,0x22,0x22,0x54,0xd3,0x13,0xe2, + 0x29,0x3e,0xd4,0x8b,0xf5,0xf0,0x64,0xba,0x06,0xbf,0x44,0x32,0x55,0xf3,0x1f,0x33, + 0x82,0x0d,0xdd,0xf4,0xc0,0x19,0xf5,0x83,0xfd,0xdf,0x8b,0x8f,0x57,0x73,0x8d,0x89, + 0x29,0x6e,0xd3,0x90,0x14,0x6c,0xaa,0x37,0xc5,0xdf,0x85,0xa7,0x56,0x5e,0xa4,0x72, + 0x69,0xd6,0x30,0x86,0x22,0xc9,0xcb,0x00,0xca,0x79,0x8f,0x0e,0xb2,0xbb,0xad,0x92, + 0x7f,0x1e,0x51,0xeb,0xc8,0x9d,0x6b,0x10,0x61,0xec,0xaa,0x05,0xf3,0x7e,0xb1,0x75, + 0xa0,0x15,0x72,0x38,0x36,0x16,0x66,0x01,0x4a,0x7b,0x65,0x17,0xc6,0x57,0x31,0xee, + 0x4c,0xd3,0x10,0xf3,0x95,0x14,0x68,0x77,0x9a,0x8a,0xc8,0x46,0x95,0x58,0x5e,0x96, + 0x08,0x37,0x12,0xec,0xc3,0x15,0x0c,0x48,0x30,0x2f,0x20,0x2a,0x5c,0xab,0x50,0x9d, + 0x09,0xa8,0xf0,0x7c,0x39,0x14,0x33,0x3e,0x70,0x33,0x80,0x92,0xde,0x59,0x87,0xf9, + 0xce,0x5d,0xae,0xbe,0x1d,0xfb,0xb0,0xc4,0xea,0x08,0x89,0x86,0x5f,0x9f,0x56,0xfd, + 0x20,0x6d,0x21,0xad,0x56,0xff,0xff,0xc3,0x34,0xdd,0x29,0x9e,0x73,0xba,0x5c,0x7a, + 0xb4,0x33,0x3a,0x33,0x52,0x07,0x3e,0xee,0xeb,0x3d,0x52,0xca,0x50,0x23,0xe9,0x9b, + 0x2d,0xdc,0xb7,0x41,0x9a,0xb6,0xaa,0x7c,0x1f,0x20,0x80,0x4f,0x96,0x7e,0xc3,0x3b, + 0xa6,0x91,0xf2,0x4b,0x88,0xbe,0xe7,0xf0,0xc4,0xa3,0x5b,0x9c,0x94,0x08,0xc8,0xe3, + 0xd0,0xbf,0x7e,0xff,0x99,0x5d,0x61,0x5a,0xce,0x66,0x1c,0x0c,0x9d,0xbe,0xb7,0xd4, + 0x77,0x00,0xfe,0x03,0xb1,0x5f,0x2a,0xda,0xbb,0x3d,0x6f,0x5e,0x26,0xbf,0x5e,0x6e, + 0x6b,0x82,0x48,0xd5,0x5a,0xbc,0x60,0xce,0xb8,0x72,0x87,0x62,0x57,0x40,0xbe,0x30, + 0xea,0xad,0x2d,0x7f,0x0e,0xbd,0x86,0xde,0x75,0xe1,0x51,0x05,0x44,0x20,0x77,0xa1, + 0xa5,0xae,0xf1,0x0c,0xf2,0x43,0x66,0x4b,0xf3,0xdc,0x82,0xb1,0x89,0x0f,0x0a,0xbb, + 0xa1,0x02,0xd6,0xf0,0xed,0x89,0xf3,0xc5,0x9e,0xc7,0xf8,0x17,0xde,0xe2,0xb3,0xb2, + 0xa2,0x8f,0x2a,0x4b,0xdd,0xa8,0x62,0x41,0x25,0xea,0x1f,0x45,0x61,0x27,0x61,0x7d, + 0x23,0x8c,0xb9,0xf4,0xf8,0x89,0x72,0xd0,0x1a,0x85,0xd1,0xa5,0xc0,0xed,0x36,0xb3, + 0x22,0x88,0xb7,0xc6,0xf8,0xa1,0x08,0x02,0xa9,0xc4,0xc9,0xd4,0xb0,0x98,0x54,0x38, + 0xf7,0xa7,0x15,0xf3,0xf9,0xfb,0x82,0xd2,0x2b,0x59,0x3b,0x52,0xcd,0x14,0xf5,0xeb, + 0x6f,0x48,0x28,0x6a,0x9b,0xee,0xa8,0x80,0xa2,0x2d,0xad,0x8d,0xad,0xea,0xd5,0x7a, + 0xea,0x89,0x78,0x0f,0x51,0x31,0x04,0xda,0x4c,0xc1,0x2c,0x62,0x28,0xe9,0x51,0x31, + 0xe1,0xa8,0x04,0xff,0xe2,0x0b,0x23,0xc7,0x34,0x27,0x2c,0x8c,0xdf,0xdb,0x22,0x4a, + 0x76,0x03,0x42,0x5f,0x70,0xfa,0x29,0x9b,0x24,0x20,0xaa,0x9d,0xf9,0x2c,0x72,0xda, + 0x29,0x3d,0xad,0xad,0xc9,0x6d,0x12,0xe1,0xc6,0xc0,0x8d,0x8c,0xa4,0x62,0xd3,0xcd, + 0x81,0xac,0xe5,0xf9,0x44,0x81,0x6d,0xcc,0x08,0xce,0xed,0xc5,0xdc,0x6f,0x33,0xdb, + 0x6d,0x3d,0xb5,0x6b,0x70,0xca,0x3d,0xc9,0x34,0xc4,0x6f,0x9f,0xff,0xe4,0xf9,0x78, + 0x20,0xef,0x44,0xa4,0x6e,0x2b,0x6a,0xa6,0x03,0x65,0x7a,0x87,0xe7,0x55,0xa0,0xe3, + 0x4b,0x90,0x27,0x11,0xa2,0x0e,0x8c,0x4c,0xe1,0xaa,0x1b,0x90,0xf4,0x81,0xde,0x81, + 0xa4,0xa2,0x03,0xdb,0x3d,0x50,0x43,0x8d,0x0b,0x36,0x29,0x86,0x47,0x3c,0x09,0x62, + 0xcf,0x9e,0x72,0x65,0x59,0x42,0xbd,0x33,0x07,0xb7,0x0d,0xc7,0x0e,0x31,0x1d,0x59, + 0x87,0xcb,0xb6,0xcc,0xd6,0x93,0x5c,0xc8,0x8b,0xd7,0x73,0xe2,0xa6,0x10,0x6e,0x2b, + 0xca,0xdf,0xcd,0xe2,0xcb,0xce,0x88,0x63,0x0d,0x8a,0x18,0x24,0x7f,0x73,0x7b,0x15, + 0x76,0x19,0xf4,0x69,0x56,0xa3,0x33,0x49,0x1d,0xfb,0xed,0x0a,0xfc,0x14,0xee,0x33, + 0x63,0xba,0xcd,0x17,0x30,0x71,0x9d,0x39,0xe3,0xfa,0x55,0x38,0x50,0x0a,0x96,0xfb, + 0x6f,0x9a,0x46,0xad,0x7e,0x35,0x4c,0xaa,0xcb,0x43,0xca,0x7e,0x99,0x87,0x6e,0x2f, + 0xd0,0x5b,0xb5,0x20,0xce,0x7b,0x13,0x5a,0x12,0x79,0x85,0xc8,0x02,0x79,0xf8,0xfa, + 0x82,0x5b,0xdc,0x8d,0xc4,0xc5,0x35,0xdf,0x6a,0x9d,0x17,0x4c,0x5e,0x3a,0x4f,0xfc, + 0x2b,0xfc,0x9f,0x60,0xbf,0x82,0x20,0xfe,0x2b,0xbb,0xc4,0xdd,0x86,0x5b,0x3e,0xa8, + 0x22,0xac,0x71,0xe8,0x51,0x33,0x07,0xd5,0x95,0xf1,0x9c,0xf9,0xf8,0x7f,0x2e,0x6e, + 0x20,0x12,0xde,0x65,0x9a,0x22,0xe1,0x6b,0x0d,0x80,0x92,0x0c,0x77,0x72,0xf8,0xd2, + 0x09,0x9a,0x47,0xbe,0x88,0x7c,0x81,0x55,0x1d,0x32,0x94,0x0f,0x78,0x36,0x16,0x40, + 0x0e,0xe0,0x7b,0xbf,0x50,0x7b,0x39,0x48,0xea,0x0f,0xf8,0xfb,0x2b,0x1b,0x5e,0x04, + 0x67,0x45,0x60,0xc7,0x5f,0xad,0xd3,0x06,0x27,0xd1,0x1c,0x59,0x68,0x1f,0x10,0xe1, + 0x27,0xef,0x04,0x89,0x14,0x21,0x8a,0x8e,0xae,0xa5,0xd8,0x34,0x54,0xec,0x77,0xb3, + 0x6f,0xe6,0x5e,0xef,0x18,0x6f,0xa6,0xd0,0x40,0x49,0x0a,0x8b,0x23,0xa3,0x4f,0x2b, + 0xa1,0x08,0xae,0xac,0xd1,0xac,0x01,0x17,0x32,0xce,0xcb,0x3f,0xd5,0xe9,0xa0,0x83, + 0x14,0x89,0xbe,0x75,0x06,0x0b,0x72,0xf1,0x68,0x1b,0x37,0x5b,0x50,0xe5,0x08,0x50, + 0x7e,0x88,0xd6,0xfe,0xdd,0xd6,0x42,0xed,0xb8,0x4e,0x00,0xf2,0x77,0xe7,0x01,0xe3, + 0xda,0x89,0xd3,0x01,0x04,0xca,0xb1,0xab,0xc6,0xaa,0xa5,0x08,0x75,0x67,0x7b,0x57, + 0x05,0x84,0x97,0x4c,0x7e,0x44,0x7b,0xed,0x30,0xc4,0xa3,0x76,0x74,0xa5,0x33,0x3b, + 0x62,0x27,0x62,0xcf,0x09,0xa5,0x4d,0xd2,0x4c,0x8a,0x2e,0xac,0x17,0x0f,0xf8,0xe9, + 0x81,0x84,0x3a,0x51,0xe4,0xd5,0x46,0x58,0xb6,0x88,0x14,0x1d,0xc8,0xcc,0x83,0xfb, + 0x68,0x29,0xc3,0xb9,0xc4,0xa5,0x34,0x6c,0x4e,0x2d,0xa5,0x4d,0xf3,0xcf,0xd4,0x3f, + 0x64,0xe8,0x02,0x60,0x08,0xf6,0x61,0x13,0xa5,0xba,0x12,0x1c,0x04,0xce,0xa7,0xa8, + 0x8c,0x4b,0x80,0x4e,0xf5,0x38,0xcc,0xc2,0xaf,0x13,0xe2,0xc7,0xaf,0xe3,0x0a,0xec, + 0x1d,0x80,0x8b,0xfe,0xc9,0x12,0x44,0xca,0x85,0xde,0x21,0x7c,0x20,0x94,0x2f,0x29, + 0xce,0x81,0xbd,0x40,0x92,0xe0,0x8c,0x69,0xe0,0xa0,0x47,0x14,0x7d,0xaf,0x94,0xa9, + 0xae,0x1d,0xc2,0x30,0x0e,0x6a,0x45,0xde,0x05,0x2c,0xa0,0x7d,0xa4,0x76,0x1a,0xe0, + 0x97,0xf5,0x0e,0x98,0x56,0x44,0x7c,0x13,0xb8,0x94,0x34,0x17,0xaa,0xbe,0xd5,0xb5, + 0x84,0xee,0x64,0x12,0x15,0x10,0x47,0x36,0x6e,0x89,0x9c,0xe7,0xd4,0x79,0x1d,0x68, + 0x08,0x9f,0xf3,0xe9,0xb2,0xb3,0x96,0xa4,0x48,0xdf,0xf7,0x61,0xb0,0xf4,0xbd,0x11, + 0x4b,0x3e,0xf4,0x82,0x60,0xdf,0x06,0x51,0x39,0x97,0x3d,0x55,0x77,0xf7,0x04,0x74, + 0x2d,0x99,0xc5,0xc1,0xbb,0x32,0x4a,0x56,0x06,0x2b,0xcc,0x19,0xb7,0x96,0x14,0x56, + 0x2c,0x34,0xec,0x96,0x55,0x08,0x83,0x0c,0x43,0xbb,0x9c,0xb2,0x24,0xfa,0xc2,0x21, + 0x66,0x3b,0x85,0xb4,0x3a,0x30,0x8a,0x90,0x8c,0x55,0x31,0x62,0xb5,0xd6,0x55,0x29, + 0x0b,0x9a,0x8f,0x55,0x46,0x31,0x3d,0xcc,0xef,0xbb,0x42,0xa5,0xf9,0x7d,0x1e,0x70, + 0x80,0x95,0x62,0xd0,0x32,0xa6,0x95,0xad,0xc0,0xbd,0x25,0xcc,0x3d,0xd8,0x9a,0xf8, + 0xd2,0xd8,0x3b,0x1a,0x15,0x6b,0x64,0xf2,0x15,0x76,0x9e,0x3b,0xf8,0x7b,0x58,0xac, + 0x0d,0x45,0xda,0x70,0xdf,0x3d,0x0f,0x9a,0x4d,0x45,0xcf,0xcd,0xbd,0xba,0x11,0x2f, + 0x4d,0x64,0x97,0x67,0xbd,0x4a,0x9f,0xc9,0x8f,0x1c,0xdf,0xbd,0xb4,0xf6,0x19,0xed, + 0x8f,0x43,0xe6,0x8e,0x4e,0xfe,0x5e,0x28,0xba,0x7f,0x72,0xc9,0xdd,0x48,0xbe,0x8a, + 0x29,0x9f,0x5a,0xbc,0xd4,0xf9,0x59,0x52,0x86,0xae,0xb4,0xeb,0xfd,0xb5,0xd3,0xa9, + 0x51,0x98,0xf7,0x66,0x1f,0xa1,0xd0,0x5f,0x3e,0x3d,0x57,0xf5,0x72,0xf3,0xf3,0xdf, + 0x8c,0x0b,0xce,0xd8,0x30,0x39,0x21,0x19,0xeb,0x5a,0x67,0x1d,0xdb,0xff,0x2f,0x7f, + 0xd9,0x9c,0x08,0x06,0xb1,0xaa,0x06,0x15,0x46,0x41,0x27,0x08,0x74,0x94,0xf1,0xd7, + 0xf8,0x87,0xc2,0xea,0xb2,0x27,0xd8,0x10,0x5a,0x4c,0xa0,0x64,0x53,0x6e,0xba,0x5b, + 0x61,0x7d,0x5e,0xe7,0x3c,0x2f,0x51,0x43,0xe1,0x31,0x82,0xa7,0x50,0xca,0x09,0x6b, + 0x43,0x43,0x81,0x90,0x30,0xa9,0x01,0x25,0xc7,0x42,0xa3,0xb7,0x59,0xbb,0xc1,0xb3, + 0xe2,0x48,0x6b,0xc1,0x81,0x1b,0xa6,0xa0,0x52,0x06,0xd8,0x71,0x61,0x81,0xe3,0xb8, + 0x47,0x69,0x08,0xb5,0x1f,0x19,0xec,0x0b,0xe0,0xb5,0x20,0x69,0xad,0xb5,0x20,0x3a, + 0x57,0x9b,0xbe,0x1a,0x27,0xda,0x5e,0x63,0x33,0x49,0xee,0x83,0xc2,0x9b,0x9d,0x0f, + 0xad,0xdb,0x76,0x1e,0x95,0x26,0xe6,0x01,0x97,0x4c,0x2c,0x51,0x0f,0xa4,0x0a,0x81, + 0xe9,0xb9,0x75,0xee,0xb9,0xa2,0x5f,0x4a,0x0a,0x47,0xea,0xae,0xd8,0x00,0x6a,0xaf, + 0xe8,0x4b,0x77,0xfe,0xb8,0xa3,0xda,0x19,0x33,0x25,0xa3,0xc0,0x55,0x2b,0xfc,0x73, + 0xea,0xd5,0x6c,0xef,0x39,0xa0,0x2d,0xfd,0x8a,0x95,0xad,0x15,0x7b,0x91,0x41,0x27, + 0x8f,0xbb,0xf4,0xff,0x1b,0x03,0xf8,0xf9,0x81,0x09,0x06,0x66,0xdf,0x92,0x2b,0xa3, + 0xe1,0xb8,0x8e,0xc8,0x3a,0x8d,0xe3,0x4c,0x21,0xfd,0x8c,0xd9,0x52,0x6a,0xca,0x9e, + 0x99,0x0e,0x0e,0x02,0x15,0x33,0x04,0x45,0x95,0xe6,0x5d,0x83,0xb2,0xae,0xe0,0x53, + 0xe1,0x7a,0x9a,0x58,0x4f,0x42,0x77,0x98,0xbe,0x42,0xf3,0xa9,0x7b,0xe4,0xa8,0xa2, + 0x62,0xa8,0xb6,0xb2,0x6a,0x6d,0x0b,0xab,0x22,0x85,0x77,0xe2,0xd8,0xcf,0xc4,0x99, + 0xeb,0xed,0xbe,0x28,0xdb,0x54,0x94,0xcc,0xdf,0xf0,0xb4,0xe1,0xd1,0x79,0xf5,0x68, + 0x29,0xaa,0x8c,0x6d,0x3d,0x73,0x0c,0x24,0x76,0x1f,0x18,0x30,0x4c,0xcd,0x90,0x6e, + 0x55,0x41,0x45,0xd0,0x94,0xa9,0x83,0xa0,0xc3,0x13,0x10,0x58,0x41,0xa9,0x0d,0x13, + 0x4f,0x5e,0x8a,0x46,0x65,0x02,0xdf,0x59,0xe7,0x1e,0x9b,0x8c,0x71,0x6e,0x3f,0xe7, + 0x83,0xab,0x3c,0xcc,0x95,0x24,0xc3,0xdb,0x16,0xc1,0xe9,0x60,0x70,0x1d,0xb1,0x3c, + 0x23,0xa8,0xf2,0xac,0x4f,0x77,0x62,0x54,0x65,0x86,0x96,0x95,0xbb,0x0f,0x1c,0x4f, + 0x07,0xc9,0x3d,0xcd,0x15,0xc9,0x42,0x65,0xbd,0xcd,0xb5,0x52,0x0b,0x34,0xd8,0x2a, + 0x16,0x84,0xc2,0xe9,0x12,0x88,0x16,0xc0,0xc1,0xf8,0xa5,0x71,0xb0,0xec,0x3e,0x77, + 0x5f,0x18,0x21,0xa0,0x3e,0xf0,0x64,0xa9,0x2e,0x43,0xf6,0xae,0x75,0xf3,0x0e,0x1c, + 0x71,0xb7,0x8c,0x6f,0xbd,0xb4,0x1a,0x3c,0x4c,0xf8,0x90,0xde,0x3a,0x84,0xc7,0x59, + 0x06,0x81,0x3d,0x72,0x05,0xbb,0x87,0xcf,0x13,0xa1,0x68,0x4f,0x7a,0x7e,0xb0,0xb4, + 0x16,0xc6,0x5e,0x19,0xf4,0xfb,0xc0,0x73,0x9e,0x6b,0xe7,0x7a,0xdd,0x15,0x3d,0x4c, + 0x73,0x18,0x9d,0xcc,0xb7,0x27,0x06,0x96,0x00,0xad,0x16,0x3c,0x69,0xd1,0xb3,0x1f, + 0x2d,0xa5,0xee,0x2f,0x98,0x2f,0x97,0xc9,0x1f,0xf2,0x1e,0x2c,0x0c,0x7b,0x7f,0x27, + 0x06,0x13,0xf1,0xab,0x60,0xb5,0x29,0xd4,0xec,0x8d,0x05,0xfe,0x94,0x71,0xb9,0x99, + 0xe9,0xc2,0x77,0xad,0x3b,0x99,0xcc,0x87,0x81,0xee,0x29,0x8e,0xff,0x7d,0x4e,0x6d, + 0x78,0xff,0x04,0x64,0x57,0x5d,0x24,0x9b,0x04,0xcf,0xb5,0xdb,0xe5,0x3b,0xa8,0xeb, + 0x05,0xef,0x0f,0x3e,0x88,0x1c,0x3e,0xb6,0x6d,0xf9,0x78,0xd6,0xcb,0xa3,0x98,0xbf, + 0x33,0x19,0xd9,0x23,0x40,0x43,0xf1,0x02,0xdd,0xcb,0x35,0xa3,0xe9,0x5e,0x16,0x81, + 0x85,0x1e,0x04,0x59,0x64,0xff,0x7b,0xd1,0x2c,0x69,0xe5,0xa5,0x3c,0x72,0x6e,0xf0, + 0x25,0x44,0xf0,0x68,0x10,0xa5,0x62,0x9c,0xad,0x87,0xca,0x95,0x30,0xe0,0x48,0x42, + 0xb3,0x52,0x44,0xd3,0xc2,0xc7,0x2c,0x35,0x8d,0x6f,0xc0,0xa6,0x0b,0x1a,0x3b,0x19, + 0x31,0xf9,0xf7,0xaf,0xda,0x7a,0x4b,0x90,0xec,0x6b,0xf6,0xe5,0x56,0xac,0xdc,0xec, + 0x5a,0xfa,0x80,0xbc,0x6c,0x5b,0x31,0xdb,0x2e,0x16,0x55,0x04,0xb1,0x11,0x40,0x0b, + 0x0d,0xba,0x62,0x5a,0xf9,0x57,0x70,0xd4,0x4a,0xe9,0xc0,0x2a,0x58,0x84,0x78,0xe5, + 0x8f,0x6e,0x6a,0x4b,0x39,0xd4,0x3c,0xbe,0x65,0x63,0x84,0x07,0xd0,0x6f,0x19,0x32, + 0x73,0x17,0x06,0x09,0x08,0xce,0x7d,0x6c,0x1a,0xc0,0x23,0x5d,0x37,0x5b,0x97,0x9f, + 0xce,0x5e,0xb9,0x0f,0x76,0xef,0x39,0xd9,0x31,0x2a,0xf9,0xff,0x5a,0xed,0xcd,0x14, + 0xbb,0x50,0x5f,0x11,0x18,0x8d,0x60,0x7a,0xb1,0x41,0x8c,0xda,0xdc,0x0b,0xfa,0x28, + 0xf0,0x70,0xfe,0x6a,0x3b,0x20,0x72,0x7a,0x87,0x8e,0xdc,0xa6,0xfc,0xaf,0x0b,0x89, + 0x08,0x7b,0x67,0xb4,0x27,0xec,0x25,0x52,0x39,0x65,0xce,0xeb,0x9d,0xc7,0xab,0x02, + 0xe1,0x82,0xb2,0x6d,0x38,0xbf,0x77,0x54,0xed,0x9a,0xb1,0x87,0x5d,0x08,0xf5,0x7c, + 0xf9,0xed,0x01,0x80,0xa0,0xd4,0xf4,0xde,0xfc,0xd6,0xf4,0x99,0x7c,0x9c,0xc4,0xf0, + 0x44,0xb1,0x09,0x90,0xa1,0xd5,0x44,0x30,0x60,0xbb,0x1b,0x21,0x1e,0x57,0x8a,0xa7, + 0x26,0x75,0x9d,0x78,0x18,0xbf,0x3d,0x14,0x87,0xf2,0x9d,0x65,0x20,0x34,0x75,0x5a, + 0x4e,0x72,0x19,0xb0,0x68,0xbc,0x05,0x63,0x12,0xdc,0x3d,0x46,0x37,0xb3,0x1b,0x05, + 0x9b,0x22,0x9c,0x06,0x3c,0xa4,0x0a,0xdb,0x2e,0xf7,0x68,0x64,0xab,0xfb,0x76,0xd0, + 0xb5,0x9d,0xad,0xb0,0x04,0xa0,0x6c,0x7a,0x54,0x35,0x53,0x04,0x14,0x6b,0x3f,0xc1, + 0x15,0xcb,0x5d,0x2f,0x5a,0xf9,0x55,0xa0,0xc2,0x94,0xaf,0xe6,0x55,0xf0,0xae,0x95, + 0xc5,0xdb,0x15,0x3f,0x57,0x2a,0xd6,0xb4,0xe9,0x0b,0x85,0x75,0x2a,0x88,0x18,0xbf, + 0xa1,0x3e,0x12,0xf1,0x9f,0xcc,0x56,0xee,0x4d,0x55,0x8c,0x5d,0xaa,0x57,0xb8,0xab, + 0x8c,0x38,0x38,0x7c,0x91,0x14,0xb6,0x76,0xce,0xdf,0xc0,0x24,0x96,0x3c,0x28,0x4b, + 0xaf,0x37,0x07,0x81,0x30,0x17,0x4f,0x8c,0x4f,0xdc,0x50,0x5e,0x26,0xea,0x17,0x64, + 0xce,0xf6,0xbe,0x7d,0x49,0x8a,0xb7,0x6f,0x4e,0xdd,0xc1,0x88,0x96,0x5e,0xb6,0xc8, + 0x3c,0x61,0x1e,0xc6,0xbe,0xbe,0xb2,0x20,0xd5,0x83,0x49,0x0c,0xda,0x0d,0x15,0xfd, + 0x8e,0x22,0x02,0xa5,0xa1,0x36,0xbe,0xda,0x4b,0xc6,0x2a,0x2e,0xfe,0x45,0xa7,0x92, + 0xc0,0x93,0xbe,0xf8,0x1b,0xc1,0x29,0x09,0xea,0x43,0xcd,0x4a,0x3f,0x9d,0xc3,0xb4, + 0xa9,0x27,0xcf,0x35,0xce,0xa9,0xf9,0xa5,0x62,0xbd,0x00,0xd9,0xdd,0x72,0xd4,0x52, + 0x2e,0x8a,0xd0,0xfa,0x1c,0x8b,0x90,0xe7,0x64,0x2c,0xee,0x22,0xb1,0xe3,0xf1,0xf2, + 0x83,0xfd,0x48,0xe5,0xae,0x83,0x42,0xcf,0xaa,0x90,0x7c,0xca,0x32,0x41,0x39,0x5c, + 0x02,0xfe,0x7c,0x15,0xfb,0x5d,0x81,0xd0,0xb8,0x62,0x00,0xd6,0x5c,0xef,0x74,0x62, + 0x98,0x0c,0xd7,0xfa,0xc5,0x20,0x67,0x0c,0x43,0x84,0x7d,0x2b,0xed,0xcc,0x95,0x2f, + 0x6a,0x09,0xbe,0x42,0xf3,0xa7,0xd0,0xbc,0x44,0x5f,0x7c,0x26,0xd1,0xb0,0x36,0x56, + 0xe2,0x86,0x57,0xb4,0x73,0xd8,0x42,0x37,0x9d,0x4f,0xa6,0xe7,0x38,0xe3,0x57,0x23, + 0xe2,0x48,0xe1,0xb6,0x1e,0x2b,0x41,0x07,0x3d,0xeb,0x33,0x7a,0x1c,0xeb,0xbd,0xa2, + 0x0f,0x47,0x5a,0xab,0xcb,0x90,0xdf,0x8d,0x25,0xbc,0x59,0x2b,0x22,0xbb,0x62,0x57, + 0xbb,0xa5,0xfb,0xf7,0x73,0x57,0xb0,0x4a,0x23,0x47,0x81,0x5e,0xa3,0xc5,0xf0,0x6b, + 0x14,0x06,0xd4,0xf3,0x3b,0x2a,0x6c,0x37,0xe8,0xb8,0xa8,0xc3,0xa0,0x05,0x8a,0xeb, + 0x0a,0xf6,0xc0,0xfc,0x27,0x4a,0x94,0x1b,0x37,0x4c,0x8d,0xdc,0x7b,0x2a,0xbf,0x6a, + 0xd8,0x04,0xf2,0xe6,0x6d,0xf4,0x09,0xdb,0x22,0xda,0x7c,0x4e,0x7a,0xe2,0x02,0x2d, + 0xde,0xe4,0xc4,0x23,0x98,0x28,0x15,0xec,0x7b,0x2f,0x7d,0x17,0x87,0xb8,0x4c,0xb0, + 0x83,0xc0,0x08,0x23,0x96,0xab,0x4e,0x1e,0xb4,0xe0,0xbd,0x8d,0x89,0x2d,0xe4,0x01, + 0xaa,0xff,0xd5,0x2f,0xee,0x25,0x03,0x70,0xc0,0x55,0x30,0x72,0x04,0xc1,0x6b,0x51, + 0xb8,0x4b,0x1b,0x1d,0x99,0xd2,0x41,0x3e,0x15,0x45,0x70,0x13,0x0e,0x93,0x3c,0x7f, + 0xad,0xa6,0xf3,0x6c,0xd2,0x72,0x72,0x9c,0x63,0x90,0x93,0xa6,0xf3,0x31,0xcc,0xe9, + 0xf8,0x7f,0xc8,0x10,0x47,0x69,0x39,0x89,0x79,0x55,0x23,0xef,0x1a,0x7e,0xbe,0x1b, + 0xa3,0x30,0x56,0xfd,0x92,0xe2,0xb6,0x9d,0x3c,0xa3,0x38,0xde,0x6d,0xce,0xb2,0x03, + 0xb2,0xce,0x4d,0xe0,0xb0,0xce,0xa5,0xc2,0x99,0xcc,0x1d,0xce,0xf7,0x72,0x3e,0xa0, + 0x3c,0x9f,0xdc,0x60,0xbf,0xb2,0x44,0x41,0xc3,0x6d,0x63,0xc0,0xfd,0x76,0x90,0xb2, + 0xd4,0x28,0xcc,0xd6,0x73,0x88,0x5a,0x40,0x00,0xdb,0xb4,0xea,0xb5,0x81,0x0e,0xfc, + 0xa4,0x1c,0xc7,0x05,0xf2,0xad,0x0d,0xc4,0x5e,0xd5,0x62,0xe4,0x7f,0x7a,0x5f,0xd1, + 0x1c,0x9a,0xdf,0x2f,0x40,0xaa,0xc8,0x75,0xc3,0x55,0x3b,0x04,0x39,0x37,0x64,0x8c, + 0x29,0xb8,0x9c,0x8d,0x6d,0x31,0x28,0x94,0x97,0xc5,0x06,0x44,0x34,0xa4,0x9e,0x70, + 0xd7,0x54,0xc3,0x9b,0x3f,0x71,0xa9,0xb9,0xe4,0x55,0xf7,0x57,0x86,0x3b,0x17,0x04, + 0xac,0x74,0x81,0x70,0xb4,0x78,0xec,0x8d,0x67,0x58,0x3b,0x28,0x2d,0x18,0xf4,0x91, + 0x0c,0xe4,0x6d,0x19,0xc4,0x08,0x77,0xa7,0x1e,0xaf,0x8f,0x40,0x04,0x39,0x14,0x6c, + 0xb6,0x58,0x02,0x49,0x34,0xb6,0x6d,0x0a,0x6c,0x5d,0x88,0x7e,0x7e,0x80,0x08,0x91, + 0x73,0xed,0x08,0x26,0xb6,0xbb,0x66,0x17,0xe6,0xab,0xde,0xe3,0xa5,0xd6,0x39,0xce, + 0x5f,0x11,0x00,0x36,0x98,0x5d,0x86,0x8b,0x5d,0x3b,0xe8,0xb2,0x91,0xa8,0x6f,0x1f, + 0x8f,0x1c,0xc8,0x1d,0xb3,0xaf,0xe6,0x67,0xe8,0x6f,0xb8,0xf0,0x1a,0xd0,0x40,0x42, + 0xb9,0x0b,0x17,0xf9,0x97,0xae,0x60,0x3b,0x50,0xdb,0x90,0xcc,0x37,0xe4,0x57,0x90, + 0x04,0x7e,0x8f,0x60,0x34,0x99,0x06,0x0a,0x9b,0x6e,0xab,0x0f,0xbe,0xa5,0x25,0xe1, + 0xa6,0x7d,0x41,0x38,0xb0,0xb9,0x27,0x45,0x3b,0xae,0xd0,0xe7,0x86,0x4f,0x11,0x33, + 0x24,0xbc,0x45,0x85,0xd9,0xab,0x2a,0xda,0xcd,0xfe,0x83,0x86,0xe9,0x4c,0xda,0x05, + 0x35,0xa0,0x0c,0xd4,0x25,0xae,0xf6,0x9e,0xa0,0x3f,0x4d,0x39,0x82,0x21,0x10,0x60, + 0xfc,0x70,0x10,0xad,0x68,0x85,0xe8,0x39,0xba,0xf9,0xa6,0x44,0x53,0xa9,0x83,0xd3, + 0x4e,0x2f,0x60,0xaf,0xb2,0x5b,0xa5,0xe7,0xf7,0xa5,0x56,0x50,0x3d,0x43,0x73,0x40, + 0xee,0xbf,0x69,0x33,0xff,0x5c,0x23,0x8c,0x38,0x18,0x98,0x64,0xd6,0x73,0xfd,0x0a, + 0x28,0x93,0x22,0x9a,0x38,0x73,0x9e,0xb9,0x3c,0xc2,0x16,0x5c,0xd2,0x17,0x92,0xe1, + 0x8f,0x6e,0x31,0x2c,0x6a,0x8d,0xfa,0x52,0x4d,0xa5,0x1a,0x4c,0x3f,0xdf,0xd3,0x6d, + 0x7f,0x9a,0x87,0xf2,0x1d,0xe8,0x72,0x74,0x75,0x36,0xe9,0xaf,0xa4,0x45,0xd3,0x79, + 0x7a,0xee,0x74,0x5d,0x9b,0x83,0x84,0xa8,0xb1,0x16,0xc5,0x38,0x20,0xe4,0x5c,0x03, + 0x2f,0xdd,0xe0,0xca,0x05,0xc8,0x45,0x33,0xaf,0x53,0xd4,0x2f,0x86,0x47,0xca,0x28, + 0x65,0x65,0xb0,0xd2,0x6b,0xef,0x1c,0x23,0x4c,0xce,0xaa,0xe0,0xa4,0x16,0x5d,0x03, + 0xf6,0x21,0xc3,0xf0,0x7f,0x71,0x0d,0xdb,0x3f,0xa2,0x56,0x6a,0x59,0xf8,0x15,0x5c, + 0x2e,0xb0,0xe4,0x44,0x3e,0x10,0x21,0xe6,0xbf,0x8d,0xfb,0xbd,0x5c,0xa9,0x44,0x35, + 0x83,0x9d,0xf4,0xa7,0x36,0xb1,0xcb,0x53,0xdb,0xe3,0xa4,0x8c,0x72,0xf1,0xec,0xeb, + 0xfc,0xfd,0x2a,0x7e,0x06,0x7a,0xc1,0xa2,0x0e,0xae,0x10,0x33,0xa0,0x93,0x5e,0xa4, + 0x05,0x2d,0xb7,0x9e,0x96,0xc0,0x65,0x5d,0xe8,0x79,0xa3,0x4f,0xb8,0x2e,0x92,0x01, + 0xd5,0x4e,0xad,0x9f,0xd2,0x93,0xfd,0x42,0x5a,0x71,0xd4,0x5c,0x0a,0xb1,0x22,0xe3, + 0x51,0x53,0xdb,0xa6,0x3e,0x06,0xdf,0x8c,0xb3,0x28,0x97,0xb8,0xc3,0x28,0xd4,0xe2, + 0xd8,0xd3,0x69,0xa9,0xb8,0x23,0x53,0xea,0xe7,0x89,0x4e,0xe9,0x9b,0x5e,0xba,0x5a, + 0x95,0x04,0x5a,0x80,0x6c,0xbe,0xc8,0xbc,0x3f,0x4b,0x5a,0x88,0x2b,0x22,0xfa,0x57, + 0xf0,0xd5,0xa5,0xc3,0x37,0xa7,0xd2,0x88,0x3a,0x96,0xcb,0xf5,0x9c,0x72,0x44,0x8b, + 0x2f,0x68,0x0e,0xae,0x18,0xf6,0x68,0x45,0x3c,0xdb,0xa6,0xa0,0x81,0xf7,0x2a,0x5a, + 0x69,0x82,0xbc,0x65,0xb0,0xdb,0xff,0xa0,0x9a,0x6d,0x86,0x8e,0xed,0xbb,0x7e,0x67, + 0x49,0x1c,0xb7,0xab,0x55,0x13,0x4e,0x50,0x87,0xa5,0x88,0x9e,0x5d,0x5b,0xe3,0xfd, + 0x4f,0xbb,0xb9,0xfd,0xdd,0xdf,0xc0,0x4a,0x52,0xe8,0xaf,0x67,0xfb,0xf9,0x36,0xd3, + 0x44,0x47,0x59,0xb7,0x1f,0x3c,0x2f,0xce,0x0d,0xc4,0xf4,0xa8,0xec,0x58,0x2d,0xbc, + 0x4e,0xbd,0x41,0xa0,0xe2,0xfc,0x46,0x05,0x98,0x66,0xd9,0x0f,0xe3,0x3d,0x95,0x36, + 0x80,0x85,0x64,0x71,0xfe,0xb2,0x8f,0x69,0x6e,0xdf,0x27,0xf5,0x36,0x9d,0x7d,0x24, + 0x29,0x6e,0x03,0x5f,0x43,0x9f,0x7b,0x0b,0xcf,0x6e,0x17,0x75,0xdd,0x29,0x7f,0xfd, + 0x00,0x0e,0xe0,0x40,0x2d,0x2f,0xcd,0x46,0xb3,0x50,0x5a,0xdf,0x23,0x60,0x58,0x19, + 0x08,0x07,0x77,0x53,0xd3,0x11,0xab,0x50,0x47,0x8b,0x25,0x6b,0x57,0xd1,0x69,0x87, + 0x7c,0x43,0xe1,0x07,0x58,0x2f,0xa9,0xda,0x3c,0x6b,0x3a,0x4b,0x05,0x9e,0xfb,0x08, + 0x20,0xbc,0x81,0x01,0x6c,0x4d,0x39,0x2f,0xe0,0xb7,0xf7,0x6a,0x28,0x9f,0xbf,0x2e, + 0x74,0xdb,0x0c,0x22,0x33,0xa4,0xfc,0x44,0xc5,0x94,0x70,0x16,0x30,0x60,0xe4,0xcb, + 0xd6,0x0f,0x91,0x77,0xb6,0xa9,0x60,0x8f,0x59,0x28,0xc0,0x70,0xde,0x24,0x81,0x91, + 0x26,0xf9,0xfb,0xad,0x2a,0x69,0x0c,0x32,0x6f,0xe7,0xaf,0x62,0x73,0xbf,0x4b,0x2e, + 0x56,0x03,0x83,0x48,0x6c,0x3c,0x99,0xcd,0xab,0x4a,0x66,0x95,0x72,0xbc,0x1a,0xa4, + 0x3b,0x8a,0xe0,0xe6,0x19,0xe8,0x0e,0x0c,0xc7,0x4a,0x2d,0xeb,0x92,0x22,0xad,0xfa, + 0xe9,0xad,0x1d,0xfe,0x3d,0x65,0x72,0x47,0x29,0x09,0x0a,0x43,0xd4,0xcf,0xbb,0xf6, + 0x61,0xc0,0xe3,0x49,0xa5,0x27,0xa4,0x28,0x45,0x46,0x9b,0x28,0x04,0x20,0x73,0x34, + 0x62,0x9a,0xe5,0x77,0xbb,0xc6,0x65,0xae,0x28,0x98,0xd7,0xfd,0xdd,0x9f,0xc2,0x33, + 0xdf,0xf0,0xf7,0x2a,0x97,0xda,0x2c,0x15,0xe6,0x41,0xf2,0x91,0x78,0xd7,0x5c,0x95, + 0xe0,0x77,0x72,0xa3,0x28,0x18,0xd6,0x88,0xb4,0x42,0xd2,0x03,0x0e,0x64,0xf8,0x16, + 0x63,0x8d,0x8b,0x54,0xa9,0x7a,0x2d,0x89,0x48,0x4a,0xd1,0x97,0xdc,0x87,0x75,0xe8, + 0xe3,0x95,0x73,0x60,0x3c,0xa2,0x3b,0x7b,0x82,0x42,0x5b,0x3a,0xff,0x01,0x6e,0xaf, + 0x50,0x45,0xbe,0x0a,0x87,0xbd,0x26,0xa4,0xe5,0x46,0xea,0xa2,0x91,0xf3,0xaa,0x14, + 0x00,0x57,0xf5,0x96,0x3d,0x73,0x42,0xbf,0x65,0x1f,0x84,0xa5,0x8d,0x90,0x90,0x78, + 0x21,0x89,0xe0,0x6e,0x51,0x24,0xb4,0xbb,0x7c,0xe6,0x72,0x56,0x7c,0x7f,0x9d,0x13, + 0x21,0xab,0x0a,0xe1,0x93,0x9d,0x7c,0x11,0x37,0xec,0x5d,0xd9,0x4e,0xd3,0x40,0x22, + 0xa0,0x5c,0x6f,0x9b,0xcb,0xc8,0xed,0xbe,0xbf,0x29,0xf3,0x15,0xee,0x66,0xc4,0xb9, + 0x80,0x70,0x92,0xe7,0x3f,0x9e,0xea,0x03,0x8b,0xfe,0xa3,0xbe,0xce,0x69,0x5e,0xb3, + 0x01,0x10,0x66,0xf3,0x6e,0xd3,0xfa,0xff,0x06,0xa2,0x3d,0x6f,0xd0,0xa0,0x35,0x53, + 0xa6,0x7d,0xff,0xd4,0x36,0x21,0x6f,0xf5,0x66,0x41,0x6f,0x47,0xe3,0xb2,0x3e,0xda, + 0x6b,0x78,0x81,0xfe,0xb5,0xce,0xc9,0xa8,0xeb,0x56,0x00,0xae,0xd1,0x7e,0x4c,0x1a, + 0xc7,0x54,0xb4,0x07,0xc2,0xb4,0xa1,0xe3,0x90,0xd3,0xe6,0x54,0x46,0xb4,0xeb,0x1b, + 0xac,0x10,0x78,0xff,0x6e,0xe5,0xf7,0x96,0xcc,0xe6,0x65,0x25,0x9b,0x85,0x55,0x0c, + 0x0a,0x7e,0xec,0x67,0x9d,0x47,0x9b,0x48,0x4a,0x59,0x87,0xac,0x10,0xa1,0x7e,0x18, + 0xdd,0x13,0x67,0xd6,0xa6,0x88,0x70,0x51,0xba,0xf8,0xa0,0xc6,0x08,0xb9,0xe1,0xa6, + 0xf6,0x5f,0xaf,0x7c,0xed,0x82,0xda,0x3e,0xf9,0x5e,0x01,0xfc,0xf8,0x73,0x7f,0x19, + 0x51,0x11,0x99,0xc2,0xbe,0x70,0x84,0xf2,0x81,0x2a,0xe4,0xe5,0x1e,0xcb,0x57,0x0e, + 0x29,0x17,0x10,0xdd,0x38,0x31,0xbc,0x02,0x94,0x5f,0x3f,0xc2,0xdf,0x11,0xf9,0x9d, + 0x3b,0x0e,0x27,0xa0,0xdf,0x2d,0x4e,0xb4,0x2f,0x66,0xfc,0x02,0x23,0xe0,0xfc,0xef, + 0x84,0x5a,0x49,0xf8,0xf4,0x97,0x02,0xc1,0x93,0x6e,0x65,0x37,0x62,0xe4,0x07,0x2e, + 0xa2,0x2d,0x0d,0x88,0x2b,0x2f,0xb1,0xd2,0x06,0x42,0x6e,0x3a,0xaf,0xe2,0x8f,0x97, + 0xda,0xcf,0xd4,0x65,0x07,0xbc,0xde,0xc2,0x1f,0xd3,0xe4,0xde,0xd3,0xe1,0x1e,0x9a, + 0x02,0xfe,0xb9,0x7c,0xb1,0xe5,0x3a,0x1d,0xe5,0xaa,0x60,0xa1,0x54,0x11,0xd7,0xc2, + 0x26,0xb5,0x44,0x14,0x94,0x71,0x7c,0x35,0xc6,0xcb,0x5b,0xe0,0x8b,0x03,0xc2,0x1d, + 0x7f,0x5a,0x0d,0xc7,0x6a,0x86,0xe1,0xa4,0xc4,0x33,0xf5,0x20,0x57,0xe8,0x6b,0xb3, + 0xed,0x81,0x0b,0x48,0x59,0x2a,0xda,0xe5,0x1b,0x21,0xc3,0x84,0x1d,0x4c,0xf9,0x95, + 0x73,0x06,0x99,0xae,0xf1,0x4a,0x4c,0xb0,0x99,0x55,0x81,0x5c,0xb7,0x09,0x75,0x0f, + 0x0b,0xb0,0xe6,0x9a,0x41,0x60,0x99,0x0c,0x91,0x2c,0x67,0xa8,0x5e,0x0b,0x96,0x33, + 0x38,0xfb,0x53,0xdc,0x9a,0x83,0x98,0x74,0x35,0x36,0x8d,0x1a,0x51,0xf1,0x8e,0xe7, + 0x53,0x70,0x91,0x58,0x03,0xd4,0x65,0x08,0xc9,0x60,0xe1,0x58,0xb5,0x0a,0x6a,0xef, + 0xef,0x83,0x9c,0xdd,0x75,0x2a,0x48,0x99,0x84,0x67,0x90,0x6a,0xb5,0x29,0x52,0x8a, + 0xd0,0x82,0x0d,0xaf,0xc5,0xbd,0x5d,0xe5,0x24,0x7b,0xfb,0x8d,0xbf,0xa1,0xf3,0xc9, + 0x8b,0xe4,0x63,0xbc,0x48,0x01,0x11,0x6f,0x1e,0x18,0x8d,0x58,0xb5,0x4b,0x0b,0x1f, + 0xa0,0x04,0x95,0xc5,0x4a,0x32,0x7a,0x88,0x1d,0x13,0x9a,0x65,0x0f,0x5b,0x7e,0x0b, + 0x87,0xf5,0x1b,0xc9,0xa1,0x6d,0x06,0x5d,0xe6,0x98,0x18,0x23,0xd7,0xb1,0xda,0x71, + 0x46,0x13,0xf7,0x96,0x33,0x01,0x04,0x62,0xb8,0xae,0x19,0x07,0x8d,0x6b,0x7f,0x1b, + 0x07,0x94,0x0c,0xf4,0xf3,0x0d,0x15,0xc1,0x53,0xb7,0x12,0x02,0x2c,0x71,0x55,0x7b, + 0x9e,0xde,0xc3,0xe8,0x3a,0x15,0x84,0xe2,0x46,0x0c,0x0a,0x7a,0xf3,0xd8,0xb0,0x32, + 0x2e,0x9b,0x04,0xf9,0x12,0xb2,0x1c,0x20,0xe0,0x21,0xb4,0xd9,0x7e,0x98,0x30,0x89, + 0xda,0x1c,0x5d,0xb6,0x33,0xd9,0x25,0xe4,0xc2,0xdc,0x5b,0x61,0x96,0x5a,0xf5,0xdc, + 0x9a,0xd4,0xc5,0x77,0x17,0x3f,0xe5,0x43,0x8c,0xa5,0xdd,0x25,0x22,0x30,0x69,0x8f, + 0x86,0xd5,0x7d,0x2a,0xa7,0x45,0xfb,0x1b,0x8c,0x9a,0x9b,0x06,0x35,0xb7,0x5d,0x82, + 0x89,0x27,0xec,0xce,0x7c,0x4c,0x8b,0xf7,0x93,0xde,0x7b,0x2a,0x3f,0xbd,0xee,0x4e, + 0xad,0x4d,0x02,0x0d,0x32,0xb3,0x8a,0xc5,0xce,0x64,0x6a,0x51,0x53,0x5f,0x90,0x56, + 0x58,0x40,0xed,0x8d,0xac,0x47,0xbf,0xa9,0x19,0xd5,0x1b,0x2a,0x07,0x57,0xe4,0x84, + 0xf2,0x80,0x2f,0x80,0xb2,0x16,0xfb,0x3e,0xae,0x28,0x87,0x51,0x40,0x0a,0x58,0xe7, + 0x0f,0x3c,0xbc,0x66,0x42,0x13,0x7c,0xee,0xc9,0x9d,0x88,0x70,0x95,0x0a,0xca,0x9c, + 0x7b,0x10,0x90,0xd9,0x9e,0x62,0x01,0x1c,0x5c,0x86,0x9d,0xa0,0x8e,0x21,0xb8,0xcf, + 0xa8,0xa4,0x47,0xbd,0xdc,0xba,0x2e,0x1a,0x4b,0x54,0xa9,0x74,0xee,0x51,0x11,0xa6, + 0x44,0x94,0xb5,0x7f,0xc3,0x10,0xc5,0x1b,0xa7,0xc4,0x50,0x84,0x22,0x2b,0xb2,0x1f, + 0xec,0xaf,0xbf,0x81,0xeb,0xbd,0xcb,0x20,0x3f,0xd2,0x02,0x00,0xdf,0x62,0xa0,0x9a, + 0x95,0x95,0x18,0x4b,0xe8,0xdd,0xa9,0x56,0xa3,0x51,0xf0,0x2a,0x68,0x95,0x37,0xf0, + 0x60,0x42,0x99,0x00,0xef,0xdd,0xd1,0x38,0x00,0x59,0x26,0x24,0x5d,0x6e,0xac,0x0a, + 0xea,0x77,0x19,0xd2,0x93,0xd6,0x9d,0xf7,0xa3,0x02,0x00,0xb1,0xa8,0xfb,0x38,0x59, + 0xf8,0x54,0x3b,0x46,0x56,0xf8,0x68,0x8f,0xbf,0xe5,0x92,0x04,0x7a,0xe5,0x92,0x69, + 0x05,0x2f,0x67,0x70,0xc7,0xa6,0xe1,0x92,0xef,0x38,0x42,0xee,0xd3,0x17,0x3d,0x33, + 0x79,0x8d,0xfa,0x1b,0x4f,0x9b,0x69,0xe5,0xea,0xc2,0xd3,0x85,0xf2,0x24,0x9b,0x33, + 0x70,0xac,0x6e,0xe4,0x7a,0xed,0x21,0x81,0xf8,0xf6,0xc9,0x51,0xc1,0x25,0x82,0xce, + 0x9a,0x0b,0x86,0x4b,0x99,0x26,0x4b,0x06,0xed,0xc8,0x2d,0x4c,0xef,0xcc,0x62,0xda, + 0x8f,0xfc,0xac,0x1b,0xdf,0x8d,0x40,0xe9,0x71,0x56,0x3e,0x5e,0x7a,0x09,0xe0,0xf2, + 0xf7,0x0a,0x24,0x0b,0x4c,0x4e,0xeb,0x0d,0x29,0x75,0x0a,0x2b,0x10,0x53,0x9b,0x02, + 0xb1,0xf6,0x2b,0x8a,0x60,0xa7,0xa3,0x59,0xbd,0x09,0x77,0x3f,0xd1,0x07,0x3a,0x5d, + 0xea,0xd9,0xe5,0xae,0xfa,0x8d,0x92,0x48,0x60,0x41,0xcd,0x46,0xda,0x0e,0xe6,0xdd, + 0xde,0x6f,0x1e,0xa2,0xe6,0xac,0x23,0x06,0xec,0x0c,0x1e,0x57,0x5d,0xd7,0x3b,0xa1, + 0x86,0xd2,0xfb,0xb2,0x73,0x21,0xa8,0x99,0x81,0xbf,0x83,0x49,0xd8,0x2c,0x22,0xb2, + 0x74,0x84,0xda,0xae,0xf5,0xf2,0xf3,0x5d,0x4e,0xae,0x4d,0x7f,0xcb,0x2d,0x56,0x33, + 0x26,0x11,0xfb,0x79,0x30,0x3e,0xb4,0x9b,0xe4,0xcf,0xaf,0x63,0xba,0xfa,0x37,0x72, + 0x8d,0xac,0x4c,0xb4,0x23,0x2a,0x96,0x72,0x67,0xb9,0x56,0x56,0x91,0x2a,0x2c,0x05, + 0x88,0x96,0xed,0x03,0x4c,0x73,0xd5,0x68,0x84,0x10,0xdd,0x9c,0x01,0xd6,0x75,0x61, + 0x3d,0xe2,0x0b,0xcb,0x3c,0x51,0x9f,0xb8,0x5b,0xa3,0x9d,0x84,0xfa,0x8c,0x18,0xc5, + 0xf3,0xe9,0x28,0x44,0xce,0x14,0x6a,0x34,0x02,0x8b,0xe2,0xec,0x99,0xf1,0x8c,0xf1, + 0x75,0x18,0x2e,0xcb,0xfd,0x9e,0x24,0xc2,0x9c,0x4e,0x73,0x07,0xa3,0x81,0x6e,0x31, + 0x40,0xc7,0x69,0x87,0x31,0xe2,0xaa,0x92,0xa9,0xa2,0x7d,0x6f,0x2f,0xcb,0xb2,0x21, + 0x6f,0xc6,0xab,0xd1,0xd8,0xb1,0x77,0x82,0x40,0x18,0xfa,0x04,0x6f,0x65,0x7f,0xee, + 0xdf,0x93,0x2d,0x09,0xab,0x07,0xb8,0x8c,0x1f,0x58,0x2f,0x1d,0xdb,0xa7,0xf6,0xbc, + 0x0b,0xba,0x4e,0xbc,0xbd,0x34,0xa5,0x08,0x99,0x86,0xf8,0x78,0x7a,0xfb,0x49,0xb4, + 0x1b,0xc7,0x78,0x7d,0x8b,0xab,0x4d,0x58,0x94,0xa5,0x22,0x6c,0x45,0x14,0x5e,0xb9, + 0xcb,0xb8,0xf0,0x19,0x92,0x5b,0xb8,0xbf,0x02,0x3f,0xc5,0x95,0x85,0xd4,0x86,0xe8, + 0xf2,0x5e,0x46,0xbe,0xd1,0xf9,0x57,0x97,0xcd,0x1d,0x3e,0x66,0x58,0xaa,0x36,0xa2, + 0xc0,0x12,0x4f,0x2f,0xdb,0x71,0x64,0x40,0x80,0x39,0x29,0x3e,0xf8,0x3b,0x53,0xc8, + 0x15,0x4b,0xb9,0xfa,0xd1,0x9b,0xea,0xd0,0x01,0x1a,0xa8,0xd3,0x0c,0x8b,0x7d,0xf4, + 0x54,0xb2,0xae,0xc7,0x6b,0x8b,0xb3,0x86,0x21,0x1b,0x68,0xd9,0x98,0x64,0x7e,0xe0, + 0x40,0x05,0xea,0xe4,0x55,0xe0,0xba,0x3d,0x42,0x08,0x50,0x92,0x76,0x23,0x12,0xa2, + 0xe7,0xc3,0x28,0x08,0xf1,0x55,0xf8,0xfb,0x21,0xfc,0x9e,0x5f,0xd9,0x6a,0x33,0xc4, + 0x6f,0xc6,0xdf,0x94,0xff,0x24,0x6f,0x18,0x40,0x5d,0xb4,0x34,0xe1,0xa6,0x39,0x59, + 0x83,0xa2,0x1f,0xe6,0x7d,0xe3,0x2f,0x51,0xa5,0x50,0xbd,0xd5,0xd3,0xc8,0xba,0x7b, + 0x00,0xae,0xb2,0x70,0xfd,0x67,0xd8,0x56,0xc3,0x65,0xeb,0x12,0xd6,0x84,0x1f,0xc4, + 0xd4,0xc4,0x48,0xa6,0x9f,0x76,0xd2,0x94,0x74,0xc2,0xf8,0x52,0xd8,0xe7,0xb3,0x3c, + 0x25,0x36,0xbb,0x05,0xea,0x09,0xb1,0xdf,0x26,0xdd,0x31,0x87,0xa7,0x1d,0xc2,0x2c, + 0x52,0x0c,0x5e,0x51,0x60,0x0c,0x23,0x77,0x60,0xd7,0x4e,0x76,0x5a,0xeb,0xfb,0x70, + 0xaf,0xed,0xfc,0x3c,0x18,0xe4,0x4c,0x2c,0xad,0x4b,0x8e,0x08,0x3a,0x65,0x52,0x0e, + 0xed,0x08,0x8d,0xef,0x81,0xbb,0xfa,0x6e,0xce,0x8b,0x5a,0x01,0x79,0x55,0x1c,0xe9, + 0x71,0x21,0xc2,0x01,0x4c,0xde,0xc7,0xaf,0x81,0x0a,0x67,0xd0,0x5f,0xe4,0x3c,0xe8, + 0x09,0x06,0x43,0x95,0xbf,0x7d,0xb1,0xb0,0xcb,0x03,0x04,0x64,0x2d,0x81,0x54,0x76, + 0x08,0xad,0xea,0x4e,0xd6,0x66,0x28,0xa2,0xe9,0x41,0x9a,0x70,0x98,0x18,0x33,0x66, + 0x09,0x8c,0xb8,0x65,0x71,0x38,0xa1,0x0c,0x7c,0x19,0xa4,0xec,0x1f,0x42,0xa1,0x29, + 0x71,0x05,0xef,0x60,0xf4,0xfb,0x2a,0x64,0x29,0xd5,0x15,0x1d,0x35,0x48,0xcb,0x39, + 0x74,0xcd,0x39,0x5b,0xc0,0x34,0x81,0xff,0xb2,0xfc,0x49,0x8c,0x33,0x44,0xe4,0xdb, + 0x41,0x2f,0x0d,0xf9,0xa1,0xf2,0x0c,0xe5,0x6a,0x6f,0x14,0x56,0xcc,0x23,0x01,0xe9, + 0xbc,0xea,0xba,0x7e,0x79,0x6d,0x06,0x17,0x96,0x25,0x39,0xab,0x8b,0xf1,0x9e,0x33, + 0x68,0xcd,0xb5,0x46,0xb2,0xb3,0x81,0xc1,0x9c,0x6d,0xcb,0xa0,0x0d,0xfd,0x29,0xf8, + 0x24,0x9e,0x01,0x12,0x60,0xd1,0x9d,0xad,0x69,0xb6,0xb9,0xab,0x75,0x3e,0x1c,0x6e, + 0xd1,0xd5,0xc3,0x37,0xaa,0xa6,0xcf,0x71,0xea,0xdc,0x63,0x62,0x56,0xb0,0x54,0x3c, + 0x8b,0x98,0x93,0xe9,0xc9,0x60,0x1b,0x0d,0x92,0x53,0x6b,0x72,0x5f,0x37,0x5a,0x47, + 0x86,0x89,0x0d,0x4d,0x94,0x60,0xf0,0x8c,0x1d,0x2b,0xcd,0x19,0x95,0x53,0x90,0xac, + 0xcf,0x9a,0x1e,0xec,0x4d,0x22,0x7d,0x0d,0x67,0xe5,0x46,0x15,0x94,0x13,0x7c,0xc8, + 0x50,0xa7,0xcf,0x65,0xc3,0x33,0x82,0xc8,0xe1,0xba,0xb5,0xac,0xa5,0xb9,0x13,0xd0, + 0xde,0x22,0x89,0x1a,0x15,0x99,0x85,0x02,0xb4,0x24,0xa9,0x3a,0x76,0xb1,0x7d,0x88, + 0xda,0x86,0x01,0xb7,0xba,0xbb,0xec,0xab,0x94,0x25,0x8d,0x54,0x9f,0xb0,0x2b,0x59, + 0x0c,0xa4,0xd0,0xf1,0xbb,0x9a,0x10,0xfc,0xe3,0x44,0x87,0x40,0x70,0x99,0xa6,0xeb, + 0x19,0xc1,0x95,0x0c,0xbd,0xfa,0xcb,0xd7,0x85,0x98,0x61,0x6a,0x5e,0x48,0x7e,0xf0, + 0x29,0x9f,0xf6,0x5a,0x7d,0xb4,0xfd,0x3a,0x7f,0xa0,0x69,0x7a,0x57,0x2f,0x1f,0xec, + 0x13,0xdc,0x50,0xeb,0x43,0x3c,0x4d,0x57,0xe8,0x36,0xcf,0x11,0x9d,0x79,0x5f,0xb9, + 0x18,0xfa,0x29,0x4f,0x9e,0x4d,0xe8,0x04,0x0e,0x0c,0x44,0x1d,0xdb,0xff,0xad,0x7f, + 0x9d,0x42,0xce,0x2e,0x92,0x24,0x62,0x21,0x18,0xbb,0xf1,0x84,0x86,0xdf,0xa1,0x7e, + 0x6a,0x22,0x90,0x11,0x72,0xde,0x83,0x3b,0xc3,0x49,0x78,0x0b,0x75,0x0f,0x1b,0xc7, + 0x15,0xff,0x89,0x67,0xf1,0x77,0x31,0xdd,0xc4,0x00,0x4e,0x25,0x53,0x6c,0x09,0xe2, + 0xa3,0x00,0xf1,0x97,0x19,0x72,0xef,0xc1,0xc9,0x4c,0xd9,0x0a,0xd9,0x0f,0x80,0xb0, + 0x05,0xb5,0xfe,0xe0,0x14,0x25,0x30,0x3f,0xf5,0xf9,0xcb,0xec,0xf7,0xe2,0x33,0x17, + 0xdd,0x0f,0x7c,0x27,0x4c,0x2a,0xe5,0x92,0xc1,0xb9,0x18,0x95,0x8a,0x98,0x81,0x80, + 0x87,0x0b,0xb8,0x36,0xc5,0x29,0x29,0xe3,0x1f,0x79,0xd5,0x25,0xda,0x27,0xcb,0x0e, + 0x72,0xfb,0xf7,0xf1,0x95,0x06,0x20,0x02,0xd6,0x48,0xc3,0x74,0x86,0x6e,0x05,0x90, + 0x3b,0xa9,0xba,0xbe,0x10,0xaa,0x4b,0xac,0xa1,0x39,0xba,0xee,0xa1,0xe4,0x10,0xde, + 0xd0,0xf4,0xf2,0x98,0x3b,0x9c,0xdd,0x5a,0x0a,0x96,0xe4,0xaf,0x32,0xdf,0xbb,0x24, + 0x77,0x48,0xb9,0x8f,0x10,0x7b,0xeb,0x0d,0x4a,0x49,0xd9,0xcf,0x99,0x7a,0x24,0x77, + 0x06,0xbd,0xd3,0x18,0x9d,0x3b,0x63,0xbb,0xcc,0x81,0x9a,0x23,0x3d,0x9f,0xe9,0x33, + 0xdf,0xbc,0x1e,0xc8,0x18,0x29,0x32,0x28,0xf7,0xc7,0x52,0x2b,0x7e,0x2e,0xe5,0x7c, + 0x89,0xf1,0xf4,0x3d,0xb8,0xa6,0x25,0xfa,0x4a,0xb2,0x62,0x01,0x78,0x0d,0x63,0x87, + 0x57,0xd3,0xfd,0x2d,0x39,0x4b,0x57,0x8b,0xe8,0xb1,0x8f,0x18,0xe9,0x9e,0x31,0xa9, + 0x83,0x00,0x96,0x6c,0xbd,0x6d,0x63,0x59,0x6a,0x70,0x9a,0x1b,0xae,0x66,0xa0,0x82, + 0x74,0xbd,0xe4,0x86,0x56,0x3f,0x54,0xdd,0x2a,0xfa,0x9e,0xa0,0xd3,0x76,0xb3,0xa1, + 0x40,0xbe,0xac,0x7d,0x13,0x4a,0x1d,0x32,0x64,0xab,0xe4,0x36,0x53,0x83,0x1f,0x05, + 0xa3,0x12,0x31,0xfa,0x13,0x69,0x5b,0x70,0xc4,0x1c,0xc5,0x3c,0x93,0x52,0xad,0xe3, + 0xd7,0xbc,0x89,0x7d,0x83,0xa8,0x47,0xb4,0x42,0x11,0xa5,0xe5,0xf9,0x7c,0xbb,0xa2, + 0x02,0x19,0xbc,0x46,0xdc,0x9b,0x55,0x92,0xe0,0x70,0x88,0x01,0x74,0xae,0x1c,0x5d, + 0x17,0xb8,0xcc,0xd4,0x33,0xb8,0x5c,0x0d,0x6b,0x17,0x2c,0xe1,0x3b,0xfc,0x38,0x3c, + 0xa2,0x57,0x05,0x45,0xcf,0x36,0xc4,0x03,0xe6,0x46,0x1a,0x61,0xd1,0xe2,0x01,0x16, + 0x61,0x17,0xad,0x62,0x50,0x38,0x10,0xf6,0x63,0x69,0x4d,0xae,0x0e,0xcb,0xa2,0xea, + 0xd7,0x7b,0xa6,0x75,0x30,0xe3,0x46,0x77,0xcd,0x87,0xf6,0x0c,0x2e,0xf5,0x99,0x67, + 0xdc,0x9a,0x89,0x8e,0xb6,0x3b,0x05,0x83,0x5a,0xfb,0xc4,0xb9,0xda,0xf4,0x61,0xeb, + 0x5f,0x97,0x87,0x70,0xa8,0x7a,0x16,0xcf,0x17,0x18,0xef,0x2f,0xfd,0xb0,0xdf,0x86, + 0x2d,0xb4,0x38,0x9c,0x34,0x37,0xa7,0x3b,0xcb,0x6b,0x60,0x39,0xd2,0x98,0x4e,0xcc, + 0x60,0x36,0x56,0x8e,0x9b,0x30,0x0f,0xfa,0x8f,0xa3,0xfd,0x92,0xab,0x3e,0x70,0x1c, + 0xa6,0xeb,0x6e,0x9e,0xb8,0x96,0xcd,0x7c,0x60,0x2f,0x73,0xb2,0x8e,0x21,0x79,0x1d, + 0xe8,0xe1,0xbf,0x8f,0x36,0x32,0x6d,0x17,0x89,0x8e,0x48,0xaf,0x67,0x83,0x07,0xdd, + 0xe3,0x55,0xa7,0x55,0xbd,0x3f,0xe0,0x1b,0x88,0x15,0x1f,0x80,0x7a,0x13,0x28,0x07, + 0xb1,0x84,0xa0,0xfb,0x1c,0xe2,0x0a,0xc0,0xc6,0xc3,0x06,0xd7,0xbc,0xa4,0x07,0xe1, + 0x27,0x3c,0x38,0x94,0x95,0x22,0x40,0xb0,0x67,0x73,0xd9,0x38,0x85,0x95,0x23,0x78, + 0x5d,0xdf,0xec,0x00,0x14,0x3f,0xf6,0x41,0x87,0x7d,0xef,0x15,0x94,0xae,0x57,0xb2, + 0x71,0x80,0xf3,0x39,0x36,0x78,0x03,0xd1,0x47,0xc7,0x9e,0xc6,0x49,0x71,0x00,0x1d, + 0xb9,0x79,0xf0,0xe7,0xff,0x1e,0xaf,0x62,0x62,0xc2,0x70,0x21,0x72,0x8a,0x57,0xb0, + 0x85,0x79,0x37,0x14,0x11,0x8d,0x00,0xf6,0x65,0x70,0x9e,0x07,0x54,0x37,0x19,0xc1, + 0x5b,0xd9,0x99,0x63,0xe1,0x82,0x51,0x23,0xa5,0x39,0x61,0x14,0xb7,0x8a,0x14,0x3c, + 0x24,0x81,0x9e,0xbf,0x75,0x7a,0x21,0xfe,0x45,0xc3,0x39,0x0a,0xe6,0xe4,0x95,0xab, + 0x28,0x25,0x82,0xf3,0x3e,0x13,0x2d,0x48,0xce,0xcb,0x5a,0xa4,0x7e,0x3e,0x3a,0x7c, + 0x0b,0x83,0x34,0x5e,0x90,0x24,0x65,0xca,0x49,0xc6,0xd2,0xb8,0xa1,0xa8,0x39,0xeb, + 0xdc,0x91,0x27,0xf7,0x9c,0xe8,0xf6,0xc9,0x4e,0x82,0xcc,0xd2,0xdc,0xe4,0x2b,0x04, + 0x09,0x5f,0x4c,0xe0,0x7c,0x7d,0x5b,0x9f,0x8c,0x89,0xdb,0x9f,0x83,0xe6,0xcd,0xa0, + 0xe7,0xd4,0x1a,0x46,0xe3,0xe3,0x6c,0x08,0x6f,0x6e,0x73,0x7f,0x7c,0xce,0x30,0x5b, + 0xac,0x8e,0xf1,0xdc,0xf1,0xe2,0x60,0x7b,0x6e,0x6d,0xbe,0x6f,0x59,0xc6,0x1b,0xc9, + 0x8f,0xf3,0xba,0xf0,0x98,0x7d,0x13,0x68,0xfa,0xc3,0xf5,0x6d,0xce,0xed,0x94,0xa0, + 0x0d,0x87,0x50,0xbd,0x33,0x52,0xbb,0x16,0xf0,0xc5,0x20,0x7d,0xd3,0xad,0x80,0x72, + 0x20,0x9f,0xcc,0x77,0xf2,0xb0,0x4c,0x20,0x46,0x60,0x6b,0xf6,0xf6,0x57,0xec,0xf4, + 0x4c,0xe0,0x29,0xe4,0xde,0x37,0x44,0xb0,0x69,0x5a,0x53,0x4c,0x51,0x0a,0xb5,0x9c, + 0x98,0x89,0x82,0x10,0xdf,0x14,0x65,0xba,0xa4,0x5f,0x98,0xd5,0x57,0x97,0x35,0xa6, + 0x4c,0xe2,0x0e,0xa1,0x69,0x56,0x39,0x51,0xe3,0x39,0x42,0xc5,0x02,0x4c,0x5a,0x07, + 0xa9,0x12,0x24,0x42,0x1d,0x32,0xe7,0x66,0x6d,0x9c,0x4b,0x69,0x89,0x29,0xa0,0xa1, + 0x6c,0x17,0x94,0x54,0x3e,0xd1,0xeb,0x0d,0x33,0x02,0x9b,0x88,0xa5,0xfd,0x65,0x83, + 0xa2,0x34,0x85,0x87,0x18,0x3b,0x4f,0x01,0x85,0x26,0x14,0x19,0x7b,0x0b,0x92,0xa0, + 0xe4,0xfb,0xd5,0x87,0xbf,0xb8,0xfc,0x99,0x90,0x42,0x79,0x30,0x77,0xd7,0x7e,0x92, + 0x1f,0xea,0xf8,0xbd,0x30,0x13,0x47,0x28,0x69,0xbc,0xd6,0x18,0xb8,0xf5,0x1c,0x65, + 0xd9,0x96,0x0f,0x84,0xa1,0x0d,0x5e,0xb8,0x6c,0xd4,0xf6,0x26,0xff,0x3e,0x9f,0x7a, + 0x0f,0x69,0x95,0x8e,0x39,0xac,0x6d,0xbb,0x4f,0x9b,0xcc,0xd4,0x71,0x6c,0x0f,0x92, + 0x44,0xea,0xf1,0x90,0xaf,0xf5,0x45,0xdb,0xb9,0x99,0xfc,0xdd,0x84,0xf2,0x81,0x0a, + 0x2a,0x3c,0x8e,0x0c,0xbd,0xf8,0xa9,0x1e,0x51,0x1a,0x5a,0x2e,0xc7,0xbd,0x14,0xa8, + 0x8c,0x9b,0x86,0xbc,0x19,0xd3,0xfe,0x93,0x78,0x29,0xd2,0x7b,0xf6,0x9d,0x2d,0xef, + 0x2c,0x62,0x8f,0xc8,0x3d,0xb1,0xae,0xeb,0x0f,0x61,0xdb,0xfa,0x77,0xae,0xc0,0x34, + 0x52,0x90,0xb6,0x8c,0x1a,0x39,0xaf,0x7f,0x97,0x76,0xd3,0xe7,0x77,0xdd,0x00,0x43, + 0x04,0x24,0x20,0x77,0xb3,0xa3,0xd0,0x9c,0x88,0xc8,0x96,0x11,0xb9,0x81,0x08,0x54, + 0xef,0x9e,0xf0,0x33,0xec,0x2e,0x60,0x14,0xc3,0x65,0xa6,0x10,0x57,0xd9,0x5f,0x01, + 0x08,0x68,0xb7,0xf6,0x1c,0xff,0x19,0xc3,0x81,0x46,0x3d,0xb7,0x8c,0x6a,0x09,0x11, + 0x84,0xe4,0x19,0xe9,0x75,0xd8,0x92,0x53,0x80,0x47,0xae,0xdd,0x0f,0x2e,0xa8,0x7d, + 0xe9,0x40,0x95,0xe5,0x30,0xde,0x30,0x20,0xe0,0x99,0xc9,0xc2,0x1e,0xc9,0xec,0x32, + 0xf4,0x8e,0xc8,0xd6,0x1a,0x98,0xc8,0xf2,0x42,0xa2,0xc2,0x8b,0x55,0x5c,0x7b,0xf1, + 0x2c,0xa9,0x95,0xe5,0xb8,0x25,0x29,0x46,0x3f,0x49,0xcb,0x85,0x82,0xcd,0xa5,0x6c, + 0x68,0x43,0xf1,0x85,0x64,0x28,0x63,0x93,0x41,0x4f,0xaa,0xf1,0xf8,0x0c,0xfb,0x08, + 0x08,0x20,0x93,0xe1,0x74,0x83,0x6a,0xac,0x6b,0x54,0x6d,0xcc,0x4c,0x73,0xdc,0x18, + 0x0f,0x0a,0xb9,0xc9,0x1f,0x40,0xf6,0xaa,0x49,0x41,0xd8,0x7c,0x09,0x6d,0xf5,0xe2, + 0x88,0x26,0xd0,0x24,0x60,0x30,0x73,0x2a,0x9d,0x47,0x26,0x4b,0x55,0xec,0x3c,0x79, + 0xdb,0x10,0xbf,0x0e,0xf5,0xf3,0x1c,0xd1,0xdb,0x06,0x1d,0xd5,0x65,0x26,0x78,0xf8, + 0xa4,0xa3,0x76,0x2e,0x59,0xf3,0xa0,0x0a,0x09,0x93,0x12,0xb8,0x10,0x2d,0x48,0xa7, + 0x2f,0x4f,0xb2,0xde,0x12,0xf0,0x50,0x38,0xe8,0x4b,0x21,0xfe,0x5a,0x88,0xe7,0x2b, + 0x07,0xd8,0xbb,0x6a,0xf9,0xde,0x2b,0x0b,0x89,0xbe,0xb3,0x2d,0x36,0x63,0x02,0x13, + 0x6a,0xa0,0xf3,0x0d,0x9f,0x20,0x53,0xcb,0x3e,0x40,0xe3,0x3a,0x0d,0x03,0x54,0x31, + 0x04,0x45,0x3b,0xc3,0xe6,0x38,0x14,0x24,0x49,0x22,0x54,0xc9,0x14,0x3e,0x08,0xfb, + 0xa0,0x1c,0x1c,0x69,0x31,0x70,0x64,0x97,0x9c,0x5e,0xa4,0x4f,0x90,0x12,0x98,0xaa, + 0xd1,0x69,0x87,0xfa,0x66,0xcd,0x75,0x01,0xa6,0xdf,0x05,0x81,0x51,0xd3,0x57,0xb9, + 0xc9,0x09,0x61,0x15,0x4d,0x13,0x8d,0xc3,0x12,0xce,0xe6,0x72,0x0c,0xc5,0xc0,0xa0, + 0x3e,0x9f,0x6c,0xec,0x22,0x7b,0xa1,0x92,0xc1,0x52,0x38,0x64,0x8e,0x54,0x9f,0x2e, + 0xfe,0x9f,0xcd,0x32,0xb6,0x64,0xa7,0x12,0xc2,0xdf,0xe4,0x07,0x07,0xd1,0xc1,0xfc, + 0x5d,0x9b,0xc4,0x23,0xa2,0x79,0x5d,0x4f,0x43,0xdc,0x79,0x67,0xf3,0xb3,0x36,0x8e, + 0x20,0x19,0x94,0xcf,0xd4,0xf1,0xda,0x13,0x61,0x5f,0x32,0xc8,0x75,0x82,0x7b,0x78, + 0xcc,0xbb,0x2a,0xce,0xbb,0x3e,0xba,0x3b,0x31,0x52,0x2d,0x36,0x79,0x98,0x75,0x61, + 0x21,0x17,0xf6,0x1e,0x38,0x86,0xde,0x98,0x43,0x54,0xfd,0x42,0x5d,0x15,0xc9,0xc3, + 0x11,0x06,0x8f,0x52,0xdb,0xaa,0xd1,0x59,0xb6,0xcb,0x28,0x36,0x07,0xa7,0x37,0x72, + 0xde,0x1b,0xb7,0x2f,0xe9,0xbb,0xe0,0x4b,0xc8,0x6b,0xa0,0x22,0x06,0xe6,0xa6,0xf7, + 0x0e,0x10,0x56,0x8b,0xc7,0x8a,0x27,0x96,0xc9,0x39,0x65,0xd0,0x86,0x8d,0xea,0x9a, + 0xaf,0x11,0x62,0xac,0xbb,0xbb,0x52,0x9f,0xca,0xd5,0x61,0xc5,0x90,0x39,0x7f,0x8b, + 0x09,0x12,0x38,0xb3,0x68,0xe1,0xe8,0x0b,0xce,0x58,0x47,0x9f,0x09,0xcc,0x27,0x28, + 0x28,0x1d,0xef,0x1d,0xab,0x53,0x5b,0x1b,0x94,0xd6,0xe5,0x41,0x10,0x1b,0x81,0x64, + 0xfb,0x9b,0x86,0x2e,0x49,0xbb,0xdc,0xb0,0x25,0xca,0x1c,0xb9,0x55,0x80,0x90,0xd5, + 0xc7,0x03,0xa9,0x65,0x21,0xee,0x18,0x5c,0x41,0x18,0xe1,0x60,0xf0,0x61,0x07,0x65, + 0xf8,0xcd,0x7d,0x74,0xac,0xed,0x37,0xa7,0xef,0x44,0x71,0xc6,0xde,0xa3,0x21,0x92, + 0xfa,0xe3,0x39,0x50,0xae,0xe7,0xfc,0x41,0x36,0x7c,0x41,0xb3,0xf6,0x2e,0x7a,0xaa, + 0xce,0x4b,0x70,0xd7,0x01,0x0f,0xc4,0x1d,0xe5,0x85,0x17,0x26,0x5a,0x8a,0x92,0x14, + 0x4b,0xc9,0xda,0x66,0xd4,0x0a,0x6f,0x71,0x2c,0x14,0x80,0x52,0x51,0x14,0xc9,0x4f, + 0xb5,0xa2,0x99,0x43,0x7f,0xfc,0xb1,0xdf,0x7a,0x6d,0xd1,0x66,0x5b,0xec,0xa9,0xbb, + 0x17,0x48,0x49,0x24,0x34,0x24,0x51,0x8a,0xf7,0x5c,0xc4,0x8a,0xe7,0x3c,0xe2,0xc3, + 0x80,0x8e,0x1c,0xe6,0x94,0x6e,0xef,0xaa,0x7b,0x29,0xeb,0x78,0xf9,0x86,0x2e,0xf8, + 0x29,0x04,0x6a,0x43,0xe4,0xa1,0xd7,0xd7,0x35,0x92,0x65,0x3f,0x5b,0xa0,0x2f,0x0c, + 0x2d,0x02,0xe1,0x1c,0xf5,0xa5,0x4e,0xc1,0xca,0x1a,0xd1,0x27,0xdd,0x5a,0x72,0x08, + 0x2a,0xca,0x2f,0x20,0xf4,0xea,0xce,0xd2,0xdd,0xd0,0xa5,0xbb,0xd8,0x2d,0xca,0x52, + 0x8b,0x8c,0xd4,0xbd,0x92,0xa1,0xc0,0x79,0x01,0xc4,0x40,0xea,0x68,0x33,0x2a,0x65, + 0x07,0xe1,0x7a,0x2c,0x2c,0x19,0xe9,0x44,0x37,0x8d,0x3c,0x7b,0x59,0xff,0x8b,0x4f, + 0xaa,0xe0,0x18,0x68,0x3f,0x51,0x55,0xa3,0xc7,0x3b,0x33,0xab,0xde,0xed,0x43,0x99, + 0x72,0x05,0x11,0xb7,0x79,0xe0,0xb4,0x83,0x4d,0xc7,0xfb,0x7b,0xa6,0x5f,0xfb,0x9e, + 0x22,0x20,0x7b,0x87,0xb4,0xf0,0x1b,0xd8,0xbd,0x92,0x57,0x58,0x50,0x8c,0xb3,0x00, + 0x2d,0x9b,0x4c,0xa9,0x11,0x3c,0xbe,0xaa,0xe5,0xbc,0x7c,0x36,0x09,0x8c,0x07,0xa7, + 0x29,0x3f,0x7a,0x87,0x37,0xbc,0xaf,0xd3,0xd7,0x89,0x0a,0xe8,0xc7,0xd8,0xa9,0x17, + 0xd3,0xa8,0xd3,0xa2,0xd6,0xfc,0xad,0xc0,0xf2,0xbf,0xab,0xd5,0x9d,0xfe,0xa4,0x82, + 0x8b,0x9a,0xde,0x59,0xc9,0x39,0xb4,0x9f,0xa4,0xd2,0xcc,0xde,0x85,0x49,0xc8,0x10, + 0x84,0x9b,0x8c,0x76,0x25,0xb6,0x1c,0xb3,0xca,0xd8,0x53,0xd2,0x57,0x34,0x0d,0x01, + 0x22,0x98,0x06,0x39,0x92,0xf7,0x7d,0x36,0x47,0x29,0xad,0x04,0x2b,0x6b,0x55,0x77, + 0x25,0x9f,0x6b,0xdf,0xd4,0xa1,0x37,0x0d,0x44,0x96,0xbd,0x30,0xc4,0xd0,0x8e,0xba, + 0xa9,0xf9,0xb0,0xbb,0x3a,0xb9,0x54,0x36,0x6f,0xca,0xa4,0xa4,0x7a,0xfb,0xe7,0x1c, + 0x2b,0x92,0xaa,0xde,0x75,0x4c,0x60,0x58,0x69,0x64,0xde,0x0c,0x4e,0xf4,0xe7,0x37, + 0x81,0xd8,0xe7,0xed,0x33,0x3c,0x00,0x67,0xa4,0x80,0xa7,0x2b,0xfe,0x93,0xbd,0x1f, + 0xc3,0x3e,0x39,0x1b,0xa8,0xab,0x0d,0x8b,0x2e,0x74,0xbd,0x5d,0xd9,0x70,0x92,0xb8, + 0x8d,0x9a,0x9e,0xe9,0x5d,0xba,0xf8,0x3a,0x54,0xdf,0x4e,0x7c,0x0e,0xee,0x6a,0x38, + 0x8e,0x17,0x96,0xf9,0x5c,0xbf,0x72,0x3f,0x7e,0x45,0xda,0xbe,0x7b,0x93,0x6f,0x6d, + 0x0f,0x16,0x9f,0xeb,0xdd,0xa8,0x27,0x36,0xab,0x46,0x4f,0x9f,0x7e,0x78,0xe8,0x8b, + 0x0f,0x90,0x97,0xfb,0xb9,0x46,0x71,0x3e,0xe0,0x25,0x6f,0xb8,0xdb,0x91,0x40,0x3f, + 0x08,0x6c,0x7f,0xe6,0x34,0xdd,0x78,0xd1,0xc3,0x50,0x98,0xa0,0x52,0x99,0x30,0x01, + 0x5d,0xf6,0x37,0x8f,0xee,0x60,0x70,0xf2,0xe0,0x02,0x08,0xb6,0x3f,0xa0,0x29,0xc3, + 0x7d,0x01,0x6d,0x9e,0x91,0xa2,0xd1,0x34,0x77,0x4c,0x00,0x0b,0x64,0x37,0x09,0x10, + 0xd5,0x0d,0x25,0x6e,0x4f,0xdc,0x79,0x91,0xcd,0xce,0xc3,0x20,0x72,0x06,0xbf,0xbf, + 0xfd,0xfb,0x3f,0xbb,0xed,0xdb,0xaf,0x9f,0xbd,0xbb,0x2f,0x9b,0xad,0x9b,0xb7,0xaf, + 0xfc,0xfa,0x37,0xab,0xec,0xda,0xa7,0x8f,0xbc,0xba,0x27,0x8b,0xac,0x9a,0xbe,0xbe, + 0x7d,0xf9,0x3e,0xba,0x6d,0xd9,0xae,0x9e,0x3d,0xb9,0x2e,0x9a,0x2d,0x99,0xb6,0xae, + 0x7c,0xf8,0x36,0xaa,0x6c,0xd8,0xa6,0x8e,0x3c,0xb8,0x26,0x8a,0x2c,0x98,0x6a,0x8e, + 0xf4,0x49,0x12,0x7e,0x2b,0xbd,0x6a,0x88,0xb7,0xf7,0xc8,0xd3,0xfb,0x29,0xf2,0x6a, + 0x3a,0xdf,0x3f,0xfa,0x9c,0xaa,0x1e,0xda,0x6d,0x4f,0x65,0x4e,0xfa,0x94,0x5a,0x93, + 0xeb,0xf5,0x7b,0x05,0x3f,0x31,0x73,0x89,0xc4,0xc1,0xf3,0x6d,0x76,0x67,0xf3,0xf1, + 0x2d,0x80,0x0b,0xfd,0xdb,0x65,0x17,0x47,0x68,0xc1,0xe3,0x19,0x5b,0x88,0xbd,0xb7, + 0xf5,0xf3,0x3d,0xb3,0xe5,0xd3,0xad,0x97,0xb5,0xb3,0x2d,0x93,0xa5,0x93,0xb5,0xa7, + 0xf4,0xf2,0x35,0xa3,0xe4,0xd2,0xa5,0x87,0xb4,0xb2,0x25,0x83,0xa4,0x92,0xbc,0xb6, + 0x75,0xf1,0x3c,0xb2,0x65,0xd1,0xac,0x96,0x35,0xb1,0x2c,0x92,0x25,0x91,0xb4,0xa6, + 0x74,0xf0,0x34,0xa2,0x64,0xd0,0xa4,0x86,0x34,0xb0,0x24,0x82,0x24,0x90,0x24,0x95, + 0xad,0x9d,0x11,0x73,0x14,0xbd,0x11,0x1f,0x68,0x30,0x11,0x20,0x58,0xa4,0xf7,0xb4, + 0xae,0x13,0x4c,0x54,0x1c,0xe6,0xdc,0x10,0xce,0x58,0xa4,0xe4,0x31,0x7e,0xe2,0x7e, + 0x41,0xc4,0x7e,0xfb,0xd0,0xa3,0xd5,0x41,0x7e,0x13,0x05,0x27,0x70,0xfa,0xba,0x90, + 0x2c,0x1f,0xcd,0x62,0x95,0xbe,0x99,0x0e,0xed,0x33,0x0d,0x31,0x87,0x2b,0xbb,0x3f, + 0xdd,0xeb,0x3b,0x3b,0xcd,0xcb,0xab,0x1f,0x9d,0xab,0x2b,0x1b,0x8d,0x8b,0xb3,0x2f, + 0xdc,0xea,0x33,0x2b,0xcc,0xca,0xa3,0x0f,0x9c,0xaa,0x23,0x0b,0x8c,0x8a,0xba,0x3e, + 0x5d,0xe9,0x3a,0x3a,0x4d,0xc9,0xaa,0x1e,0x1d,0xa9,0x2a,0x1a,0x0d,0x89,0xb2,0x2e, + 0x5c,0xe8,0x32,0x2a,0x4c,0xc8,0xa2,0x0e,0x1c,0xa8,0x22,0x0a,0x0c,0x88,0x6e,0x88, + 0x43,0xfc,0xdf,0x0c,0x9f,0x3e,0x96,0x48,0xf6,0x1a,0x56,0xd9,0x79,0x39,0xee,0xa7, + 0x0d,0x57,0xcb,0x7a,0x1d,0xc4,0x1e,0x45,0x79,0xe2,0xb9,0x4a,0x5d,0x7f,0x03,0x89, + 0x2b,0x14,0xf1,0xc7,0x1b,0x21,0x88,0xa0,0xcc,0x81,0x28,0x9d,0xb4,0x61,0x4f,0xeb, + 0x42,0x92,0xa9,0x49,0x1a,0xbe,0x51,0x55,0x69,0x60,0x97,0xda,0x04,0x74,0xb9,0x37, + 0xd5,0xe3,0x39,0x33,0xc5,0xc3,0xa9,0x17,0x95,0xa3,0x29,0x13,0x85,0x83,0xb1,0x27, + 0xd4,0xe2,0x31,0x23,0xc4,0xc2,0xa1,0x07,0x94,0xa2,0x21,0x03,0x84,0x82,0xb8,0x36, + 0x55,0xe1,0x38,0x32,0x45,0xc1,0xa8,0x16,0x15,0xa1,0x28,0x12,0x05,0x81,0xb0,0x26, + 0x54,0xe0,0x30,0x22,0x44,0xc0,0xa0,0x06,0x14,0xa0,0x20,0x02,0x04,0x80,0xdf,0xe4, + 0xe5,0x90,0xa1,0x82,0x62,0x6c,0x4f,0xc0,0xc6,0xe8,0xa2,0x54,0xf7,0x85,0x77,0xd0, + 0x36,0x0d,0x28,0x6a,0xe3,0xa7,0x40,0x16,0x43,0xc2,0x78,0x1a,0x9c,0xe0,0xd9,0x27, + 0xf7,0xb4,0x7e,0xf3,0xe3,0xe2,0x0e,0x41,0x85,0xe2,0xeb,0xd8,0x77,0xa3,0x91,0xfd, + 0x95,0xce,0xa1,0x5a,0xf6,0xc3,0xc5,0x53,0xc9,0x34,0x3e,0x32,0xd3,0x7a,0x9f,0xbd, + 0xf9,0x7b,0x1f,0xb9,0xe9,0x5b,0x8f,0x9d,0xb9,0x3b,0x0f,0x99,0xa9,0x1b,0x97,0xad, + 0xf8,0x7a,0x17,0xa9,0xe8,0x5a,0x87,0x8d,0xb8,0x3a,0x07,0x89,0xa8,0x1a,0x9e,0xbc, + 0x79,0x79,0x1e,0xb8,0x69,0x59,0x8e,0x9c,0x39,0x39,0x0e,0x98,0x29,0x19,0x96,0xac, + 0x78,0x78,0x16,0xa8,0x68,0x58,0x86,0x8c,0x38,0x38,0x06,0x88,0x28,0x18,0xdf,0xf7, + 0xcf,0x53,0xda,0x8c,0x1d,0xf0,0xb6,0x2f,0x48,0x31,0x13,0x0a,0xd9,0x6b,0x86,0x64, + 0x6c,0x8d,0x51,0x60,0x7d,0xa9,0xaa,0xbe,0x6f,0xa6,0xe3,0x10,0xfa,0xa8,0xc4,0x0f, + 0xa1,0x74,0x99,0xed,0xb8,0x27,0x36,0xaf,0xef,0xbc,0x1f,0xdf,0xcc,0x1c,0x49,0x19, + 0x8c,0xcb,0x6b,0xdf,0xb0,0x7c,0x63,0x3e,0xc9,0x32,0xeb,0x32,0x95,0xa7,0x9d,0xb5, + 0xf1,0x73,0x1d,0xb1,0xe1,0x53,0x8d,0x95,0xb1,0x33,0x0d,0x91,0xa1,0x13,0x95,0xa5, + 0xf0,0x72,0x15,0xa1,0xe0,0x52,0x85,0x85,0xb0,0x32,0x05,0x81,0xa0,0x12,0x9c,0xb4, + 0x71,0x71,0x1c,0xb0,0x61,0x51,0x8c,0x94,0x31,0x31,0x0c,0x90,0x21,0x11,0x94,0xa4, + 0x70,0x70,0x14,0xa0,0x60,0x50,0x84,0x84,0x30,0x30,0x04,0x80,0x20,0x10,0x7d,0x81, + 0xc3,0x96,0xb3,0x79,0xd5,0x13,0x64,0x4f,0x6c,0x90,0x24,0x24,0x75,0x0e,0x54,0x54, + 0x91,0xd0,0x8c,0x6b,0x24,0x0a,0x63,0xf0,0xd9,0xcb,0x43,0x49,0x8a,0x0e,0x2d,0x2c, + 0x07,0x12,0xdd,0x79,0x90,0x69,0x75,0x99,0x97,0xf6,0x8f,0x45,0xd0,0x0d,0x17,0x60, + 0xd8,0x3c,0xf8,0x6f,0xb5,0xf1,0x8c,0x66,0x9a,0xdf,0x42,0x48,0x0a,0x0c,0x9b,0x3d, + 0xd9,0x6b,0x1b,0x39,0xc9,0x4b,0x8b,0x1d,0x99,0x2b,0x0b,0x19,0x89,0x0b,0x93,0x2d, + 0xd8,0x6a,0x13,0x29,0xc8,0x4a,0x83,0x0d,0x98,0x2a,0x03,0x09,0x88,0x0a,0x9a,0x3c, + 0x59,0x69,0x1a,0x38,0x49,0x49,0x8a,0x1c,0x19,0x29,0x0a,0x18,0x09,0x09,0x92,0x2c, + 0x58,0x68,0x12,0x28,0x48,0x48,0x82,0x0c,0x18,0x28,0x02,0x08,0x08,0x08,0x7e,0xcc, + 0x04,0xd4,0x38,0xce,0x18,0xfa,0xed,0xbd,0x68,0xb1,0x49,0x51,0x83,0x07,0x16,0xca, + 0xad,0x96,0x31,0x0f,0x76,0x13,0x5e,0xb8,0x6c,0xd4,0x41,0x41,0x82,0x06,0xb1,0x09, + 0x2c,0x12,0xef,0xcf,0xba,0xb8,0xd8,0x2f,0xdd,0xc5,0x48,0x50,0x03,0x05,0xbf,0xd9, + 0x0c,0x97,0xe1,0xbb,0xbb,0xb1,0x4d,0x95,0xe1,0x50,0x40,0x40,0x02,0x04,0x99,0x35, + 0xd1,0x63,0x19,0x31,0xc1,0x43,0x89,0x15,0x91,0x23,0x09,0x11,0x81,0x03,0x91,0x25, + 0xd0,0x62,0x11,0x21,0xc0,0x42,0x81,0x05,0x90,0x22,0x01,0x01,0x80,0x02,0x98,0x34, + 0x51,0x61,0x18,0x30,0x41,0x41,0x88,0x14,0x11,0x21,0x08,0x10,0x01,0x01,0x90,0x24, + 0x50,0x60,0x10,0x20,0x40,0x40,0x80,0x04,0x10,0x20,0x00,0x00,0x00,0x00,0xff,0xff, + 0xff,0xff,0x7f,0xfb,0xef,0xdf,0xef,0xdf,0xbf,0xbf,0x6f,0xdb,0xaf,0x9f,0xf7,0xef, + 0xfe,0xfe,0x77,0xeb,0xee,0xde,0xe7,0xcf,0xbe,0xbe,0x67,0xcb,0xae,0x9e,0xfe,0xfe, + 0x7f,0xfd,0x7e,0xfa,0x6f,0xdd,0xee,0xde,0x3f,0xbd,0x6e,0xda,0x2f,0x9d,0xf6,0xee, + 0x7e,0xfc,0x76,0xea,0x6e,0xdc,0xe6,0xce,0x3e,0xbc,0x66,0xca,0x2e,0x9c,0xbf,0xbf, + 0xfd,0xfb,0x3f,0xbb,0xed,0xdb,0xaf,0x9f,0xbd,0xbb,0x2f,0x9b,0xad,0x9b,0xb7,0xaf, + 0xfc,0xfa,0x37,0xab,0xec,0xda,0xa7,0x8f,0xbc,0xba,0x27,0x8b,0xac,0x9a,0xbe,0xbe, + 0x7d,0xf9,0x3e,0xba,0x6d,0xd9,0xae,0x9e,0x3d,0xb9,0x2e,0x9a,0x2d,0x99,0xb6,0xae, + 0x7c,0xf8,0x36,0xaa,0x6c,0xd8,0xa6,0x8e,0x3c,0xb8,0x26,0x8a,0x2c,0x98,0xfd,0xf7, + 0xf7,0xf7,0x7d,0xf3,0xe7,0xd7,0xed,0xd7,0xb7,0xb7,0x6d,0xd3,0xa7,0x97,0xf5,0xe7, + 0xf6,0xf6,0x75,0xe3,0xe6,0xd6,0xe5,0xc7,0xb6,0xb6,0x65,0xc3,0xa6,0x96,0xfc,0xf6, + 0x77,0xf5,0x7c,0xf2,0x67,0xd5,0xec,0xd6,0x37,0xb5,0x6c,0xd2,0x27,0x95,0xf4,0xe6, + 0x76,0xf4,0x74,0xe2,0x66,0xd4,0xe4,0xc6,0x36,0xb4,0x64,0xc2,0x26,0x94,0xbd,0xb7, + 0xf5,0xf3,0x3d,0xb3,0xe5,0xd3,0xad,0x97,0xb5,0xb3,0x2d,0x93,0xa5,0x93,0xb5,0xa7, + 0xf4,0xf2,0x35,0xa3,0xe4,0xd2,0xa5,0x87,0xb4,0xb2,0x25,0x83,0xa4,0x92,0xbc,0xb6, + 0x75,0xf1,0x3c,0xb2,0x65,0xd1,0xac,0x96,0x35,0xb1,0x2c,0x92,0x25,0x91,0xb4,0xa6, + 0x74,0xf0,0x34,0xa2,0x64,0xd0,0xa4,0x86,0x34,0xb0,0x24,0x82,0x24,0x90,0xfb,0x7f, + 0xdf,0xef,0x7b,0x7b,0xcf,0xcf,0xeb,0x5f,0x9f,0xaf,0x6b,0x5b,0x8f,0x8f,0xf3,0x6f, + 0xde,0xee,0x73,0x6b,0xce,0xce,0xe3,0x4f,0x9e,0xae,0x63,0x4b,0x8e,0x8e,0xfa,0x7e, + 0x5f,0xed,0x7a,0x7a,0x4f,0xcd,0xea,0x5e,0x1f,0xad,0x6a,0x5a,0x0f,0x8d,0xf2,0x6e, + 0x5e,0xec,0x72,0x6a,0x4e,0xcc,0xe2,0x4e,0x1e,0xac,0x62,0x4a,0x0e,0x8c,0xbb,0x3f, + 0xdd,0xeb,0x3b,0x3b,0xcd,0xcb,0xab,0x1f,0x9d,0xab,0x2b,0x1b,0x8d,0x8b,0xb3,0x2f, + 0xdc,0xea,0x33,0x2b,0xcc,0xca,0xa3,0x0f,0x9c,0xaa,0x23,0x0b,0x8c,0x8a,0xba,0x3e, + 0x5d,0xe9,0x3a,0x3a,0x4d,0xc9,0xaa,0x1e,0x1d,0xa9,0x2a,0x1a,0x0d,0x89,0xb2,0x2e, + 0x5c,0xe8,0x32,0x2a,0x4c,0xc8,0xa2,0x0e,0x1c,0xa8,0x22,0x0a,0x0c,0x88,0xf9,0x77, + 0xd7,0xe7,0x79,0x73,0xc7,0xc7,0xe9,0x57,0x97,0xa7,0x69,0x53,0x87,0x87,0xf1,0x67, + 0xd6,0xe6,0x71,0x63,0xc6,0xc6,0xe1,0x47,0x96,0xa6,0x61,0x43,0x86,0x86,0xf8,0x76, + 0x57,0xe5,0x78,0x72,0x47,0xc5,0xe8,0x56,0x17,0xa5,0x68,0x52,0x07,0x85,0xf0,0x66, + 0x56,0xe4,0x70,0x62,0x46,0xc4,0xe0,0x46,0x16,0xa4,0x60,0x42,0x06,0x84,0xb9,0x37, + 0xd5,0xe3,0x39,0x33,0xc5,0xc3,0xa9,0x17,0x95,0xa3,0x29,0x13,0x85,0x83,0xb1,0x27, + 0xd4,0xe2,0x31,0x23,0xc4,0xc2,0xa1,0x07,0x94,0xa2,0x21,0x03,0x84,0x82,0xb8,0x36, + 0x55,0xe1,0x38,0x32,0x45,0xc1,0xa8,0x16,0x15,0xa1,0x28,0x12,0x05,0x81,0xb0,0x26, + 0x54,0xe0,0x30,0x22,0x44,0xc0,0xa0,0x06,0x14,0xa0,0x20,0x02,0x04,0x80,0xdf,0xfd, + 0xfb,0x7f,0x5f,0xf9,0xeb,0x5f,0xcf,0xdd,0xbb,0x3f,0x4f,0xd9,0xab,0x1f,0xd7,0xed, + 0xfa,0x7e,0x57,0xe9,0xea,0x5e,0xc7,0xcd,0xba,0x3e,0x47,0xc9,0xaa,0x1e,0xde,0xfc, + 0x7b,0x7d,0x5e,0xf8,0x6b,0x5d,0xce,0xdc,0x3b,0x3d,0x4e,0xd8,0x2b,0x1d,0xd6,0xec, + 0x7a,0x7c,0x56,0xe8,0x6a,0x5c,0xc6,0xcc,0x3a,0x3c,0x46,0xc8,0x2a,0x1c,0x9f,0xbd, + 0xf9,0x7b,0x1f,0xb9,0xe9,0x5b,0x8f,0x9d,0xb9,0x3b,0x0f,0x99,0xa9,0x1b,0x97,0xad, + 0xf8,0x7a,0x17,0xa9,0xe8,0x5a,0x87,0x8d,0xb8,0x3a,0x07,0x89,0xa8,0x1a,0x9e,0xbc, + 0x79,0x79,0x1e,0xb8,0x69,0x59,0x8e,0x9c,0x39,0x39,0x0e,0x98,0x29,0x19,0x96,0xac, + 0x78,0x78,0x16,0xa8,0x68,0x58,0x86,0x8c,0x38,0x38,0x06,0x88,0x28,0x18,0xdd,0xf5, + 0xf3,0x77,0x5d,0xf1,0xe3,0x57,0xcd,0xd5,0xb3,0x37,0x4d,0xd1,0xa3,0x17,0xd5,0xe5, + 0xf2,0x76,0x55,0xe1,0xe2,0x56,0xc5,0xc5,0xb2,0x36,0x45,0xc1,0xa2,0x16,0xdc,0xf4, + 0x73,0x75,0x5c,0xf0,0x63,0x55,0xcc,0xd4,0x33,0x35,0x4c,0xd0,0x23,0x15,0xd4,0xe4, + 0x72,0x74,0x54,0xe0,0x62,0x54,0xc4,0xc4,0x32,0x34,0x44,0xc0,0x22,0x14,0x9d,0xb5, + 0xf1,0x73,0x1d,0xb1,0xe1,0x53,0x8d,0x95,0xb1,0x33,0x0d,0x91,0xa1,0x13,0x95,0xa5, + 0xf0,0x72,0x15,0xa1,0xe0,0x52,0x85,0x85,0xb0,0x32,0x05,0x81,0xa0,0x12,0x9c,0xb4, + 0x71,0x71,0x1c,0xb0,0x61,0x51,0x8c,0x94,0x31,0x31,0x0c,0x90,0x21,0x11,0x94,0xa4, + 0x70,0x70,0x14,0xa0,0x60,0x50,0x84,0x84,0x30,0x30,0x04,0x80,0x20,0x10,0xdb,0x7d, + 0xdb,0x6f,0x5b,0x79,0xcb,0x4f,0xcb,0x5d,0x9b,0x2f,0x4b,0x59,0x8b,0x0f,0xd3,0x6d, + 0xda,0x6e,0x53,0x69,0xca,0x4e,0xc3,0x4d,0x9a,0x2e,0x43,0x49,0x8a,0x0e,0xda,0x7c, + 0x5b,0x6d,0x5a,0x78,0x4b,0x4d,0xca,0x5c,0x1b,0x2d,0x4a,0x58,0x0b,0x0d,0xd2,0x6c, + 0x5a,0x6c,0x52,0x68,0x4a,0x4c,0xc2,0x4c,0x1a,0x2c,0x42,0x48,0x0a,0x0c,0x9b,0x3d, + 0xd9,0x6b,0x1b,0x39,0xc9,0x4b,0x8b,0x1d,0x99,0x2b,0x0b,0x19,0x89,0x0b,0x93,0x2d, + 0xd8,0x6a,0x13,0x29,0xc8,0x4a,0x83,0x0d,0x98,0x2a,0x03,0x09,0x88,0x0a,0x9a,0x3c, + 0x59,0x69,0x1a,0x38,0x49,0x49,0x8a,0x1c,0x19,0x29,0x0a,0x18,0x09,0x09,0x92,0x2c, + 0x58,0x68,0x12,0x28,0x48,0x48,0x82,0x0c,0x18,0x28,0x02,0x08,0x08,0x08,0xd9,0x75, + 0xd3,0x67,0x59,0x71,0xc3,0x47,0xc9,0x55,0x93,0x27,0x49,0x51,0x83,0x07,0xd1,0x65, + 0xd2,0x66,0x51,0x61,0xc2,0x46,0xc1,0x45,0x92,0x26,0x41,0x41,0x82,0x06,0xd8,0x74, + 0x53,0x65,0x58,0x70,0x43,0x45,0xc8,0x54,0x13,0x25,0x48,0x50,0x03,0x05,0xd0,0x64, + 0x52,0x64,0x50,0x60,0x42,0x44,0xc0,0x44,0x12,0x24,0x40,0x40,0x02,0x04,0x99,0x35, + 0xd1,0x63,0x19,0x31,0xc1,0x43,0x89,0x15,0x91,0x23,0x09,0x11,0x81,0x03,0x91,0x25, + 0xd0,0x62,0x11,0x21,0xc0,0x42,0x81,0x05,0x90,0x22,0x01,0x01,0x80,0x02,0x98,0x34, + 0x51,0x61,0x18,0x30,0x41,0x41,0x88,0x14,0x11,0x21,0x08,0x10,0x01,0x01,0x90,0x24, + 0x50,0x60,0x10,0x20,0x40,0x40,0x80,0x04,0x10,0x20,0x00,0x00,0x00,0x00,0xff,0xff, + 0xff,0xff,0x7f,0xfb,0xef,0xdf,0xef,0xdf,0xbf,0xbf,0x6f,0xdb,0xaf,0x9f,0xf7,0xef, + 0xfe,0xfe,0x77,0xeb,0xee,0xde,0xe7,0xcf,0xbe,0xbe,0x67,0xcb,0xae,0x9e,0xfe,0xfe, + 0x7f,0xfd,0x7e,0xfa,0x6f,0xdd,0xee,0xde,0x3f,0xbd,0x6e,0xda,0x2f,0x9d,0xf6,0xee, + 0x7e,0xfc,0x76,0xea,0x6e,0xdc,0xe6,0xce,0x3e,0xbc,0x66,0xca,0x2e,0x9c,0xbf,0xbf, + 0xfd,0xfb,0x3f,0xbb,0xed,0xdb,0xaf,0x9f,0xbd,0xbb,0x2f,0x9b,0xad,0x9b,0xb7,0xaf, + 0xfc,0xfa,0x37,0xab,0xec,0xda,0xa7,0x8f,0xbc,0xba,0x27,0x8b,0xac,0x9a,0xbe,0xbe, + 0x7d,0xf9,0x3e,0xba,0x6d,0xd9,0xae,0x9e,0x3d,0xb9,0x2e,0x9a,0x2d,0x99,0xb6,0xae, + 0x7c,0xf8,0x36,0xaa,0x6c,0xd8,0xa6,0x8e,0x3c,0xb8,0x26,0x8a,0x2c,0x98,0xfd,0xf7, + 0xf7,0xf7,0x7d,0xf3,0xe7,0xd7,0xed,0xd7,0xb7,0xb7,0x6d,0xd3,0xa7,0x97,0xf5,0xe7, + 0xf6,0xf6,0x75,0xe3,0xe6,0xd6,0xe5,0xc7,0xb6,0xb6,0x65,0xc3,0xa6,0x96,0xfc,0xf6, + 0x77,0xf5,0x7c,0xf2,0x67,0xd5,0xec,0xd6,0x37,0xb5,0x6c,0xd2,0x27,0x95,0xf4,0xe6, + 0x76,0xf4,0x74,0xe2,0x66,0xd4,0xe4,0xc6,0x36,0xb4,0x64,0xc2,0x26,0x94,0xbd,0xb7, + 0xf5,0xf3,0x3d,0xb3,0xe5,0xd3,0xad,0x97,0xb5,0xb3,0x2d,0x93,0xa5,0x93,0xb5,0xa7, + 0xf4,0xf2,0x35,0xa3,0xe4,0xd2,0xa5,0x87,0xb4,0xb2,0x25,0x83,0xa4,0x92,0xbc,0xb6, + 0x75,0xf1,0x3c,0xb2,0x65,0xd1,0xac,0x96,0x35,0xb1,0x2c,0x92,0x25,0x91,0xb4,0xa6, + 0x74,0xf0,0x34,0xa2,0x64,0xd0,0xa4,0x86,0x34,0xb0,0x24,0x82,0x24,0x90,0xfb,0x7f, + 0xdf,0xef,0x7b,0x7b,0xcf,0xcf,0xeb,0x5f,0x9f,0xaf,0x6b,0x5b,0x8f,0x8f,0xf3,0x6f, + 0xde,0xee,0x73,0x6b,0xce,0xce,0xe3,0x4f,0x9e,0xae,0x63,0x4b,0x8e,0x8e,0xfa,0x7e, + 0x5f,0xed,0x7a,0x7a,0x4f,0xcd,0xea,0x5e,0x1f,0xad,0x6a,0x5a,0x0f,0x8d,0xf2,0x6e, + 0x5e,0xec,0x72,0x6a,0x4e,0xcc,0xe2,0x4e,0x1e,0xac,0x62,0x4a,0x0e,0x8c,0xbb,0x3f, + 0xdd,0xeb,0x3b,0x3b,0xcd,0xcb,0xab,0x1f,0x9d,0xab,0x2b,0x1b,0x8d,0x8b,0xb3,0x2f, + 0xdc,0xea,0x33,0x2b,0xcc,0xca,0xa3,0x0f,0x9c,0xaa,0x23,0x0b,0x8c,0x8a,0xba,0x3e, + 0x5d,0xe9,0x3a,0x3a,0x4d,0xc9,0xaa,0x1e,0x1d,0xa9,0x2a,0x1a,0x0d,0x89,0xb2,0x2e, + 0x5c,0xe8,0x32,0x2a,0x4c,0xc8,0xa2,0x0e,0x1c,0xa8,0x22,0x0a,0x0c,0x88,0xf9,0x77, + 0xd7,0xe7,0x79,0x73,0xc7,0xc7,0xe9,0x57,0x97,0xa7,0x69,0x53,0x87,0x87,0xf1,0x67, + 0xd6,0xe6,0x71,0x63,0xc6,0xc6,0xe1,0x47,0x96,0xa6,0x61,0x43,0x86,0x86,0xf8,0x76, + 0x57,0xe5,0x78,0x72,0x47,0xc5,0xe8,0x56,0x17,0xa5,0x68,0x52,0x07,0x85,0xf0,0x66, + 0x56,0xe4,0x70,0x62,0x46,0xc4,0xe0,0x46,0x16,0xa4,0x60,0x42,0x06,0x84,0xb9,0x37, + 0xd5,0xe3,0x39,0x33,0xc5,0xc3,0xa9,0x17,0x95,0xa3,0x29,0x13,0x85,0x83,0xb1,0x27, + 0xd4,0xe2,0x31,0x23,0xc4,0xc2,0xa1,0x07,0x94,0xa2,0x21,0x03,0x84,0x82,0xb8,0x36, + 0x55,0xe1,0x38,0x32,0x45,0xc1,0xa8,0x16,0x15,0xa1,0x28,0x12,0x05,0x81,0xb0,0x26, + 0x54,0xe0,0x30,0x22,0x44,0xc0,0xa0,0x06,0x14,0xa0,0x20,0x02,0x04,0x80,0xdf,0xfd, + 0xfb,0x7f,0x5f,0xf9,0xeb,0x5f,0xcf,0xdd,0xbb,0x3f,0x4f,0xd9,0xab,0x1f,0xd7,0xed, + 0xfa,0x7e,0x57,0xe9,0xea,0x5e,0xc7,0xcd,0xba,0x3e,0x47,0xc9,0xaa,0x1e,0xde,0xfc, + 0x7b,0x7d,0x5e,0xf8,0x6b,0x5d,0xce,0xdc,0x3b,0x3d,0x4e,0xd8,0x2b,0x1d,0xd6,0xec, + 0x7a,0x7c,0x56,0xe8,0x6a,0x5c,0xc6,0xcc,0x3a,0x3c,0x46,0xc8,0x2a,0x1c,0x9f,0xbd, + 0xf9,0x7b,0x1f,0xb9,0xe9,0x5b,0x8f,0x9d,0xb9,0x3b,0x0f,0x99,0xa9,0x1b,0x97,0xad, + 0xf8,0x7a,0x17,0xa9,0xe8,0x5a,0x87,0x8d,0xb8,0x3a,0x07,0x89,0xa8,0x1a,0x9e,0xbc, + 0x79,0x79,0x1e,0xb8,0x69,0x59,0x8e,0x9c,0x39,0x39,0x0e,0x98,0x29,0x19,0x96,0xac, + 0x78,0x78,0x16,0xa8,0x68,0x58,0x86,0x8c,0x38,0x38,0x06,0x88,0x28,0x18,0xdd,0xf5, + 0xf3,0x77,0x5d,0xf1,0xe3,0x57,0xcd,0xd5,0xb3,0x37,0x4d,0xd1,0xa3,0x17,0xd5,0xe5, + 0xf2,0x76,0x55,0xe1,0xe2,0x56,0xc5,0xc5,0xb2,0x36,0x45,0xc1,0xa2,0x16,0xdc,0xf4, + 0x73,0x75,0x5c,0xf0,0x63,0x55,0xcc,0xd4,0x33,0x35,0x4c,0xd0,0x23,0x15,0xd4,0xe4, + 0x72,0x74,0x54,0xe0,0x62,0x54,0xc4,0xc4,0x32,0x34,0x44,0xc0,0x22,0x14,0x9d,0xb5, + 0xf1,0x73,0x1d,0xb1,0xe1,0x53,0x8d,0x95,0xb1,0x33,0x0d,0x91,0xa1,0x13,0x95,0xa5, + 0xf0,0x72,0x15,0xa1,0xe0,0x52,0x85,0x85,0xb0,0x32,0x05,0x81,0xa0,0x12,0x9c,0xb4, + 0x71,0x71,0x1c,0xb0,0x61,0x51,0x8c,0x94,0x31,0x31,0x0c,0x90,0x21,0x11,0x94,0xa4, + 0x70,0x70,0x14,0xa0,0x60,0x50,0x84,0x84,0x30,0x30,0x04,0x80,0x20,0x10,0xdb,0x7d, + 0xdb,0x6f,0x5b,0x79,0xcb,0x4f,0xcb,0x5d,0x9b,0x2f,0x4b,0x59,0x8b,0x0f,0xd3,0x6d, + 0xda,0x6e,0x53,0x69,0xca,0x4e,0xc3,0x4d,0x9a,0x2e,0x43,0x49,0x8a,0x0e,0xda,0x7c, + 0x5b,0x6d,0x5a,0x78,0x4b,0x4d,0xca,0x5c,0x1b,0x2d,0x4a,0x58,0x0b,0x0d,0xd2,0x6c, + 0x5a,0x6c,0x52,0x68,0x4a,0x4c,0xc2,0x4c,0x1a,0x2c,0x42,0x48,0x0a,0x0c,0x9b,0x3d, + 0xd9,0x6b,0x1b,0x39,0xc9,0x4b,0x8b,0x1d,0x99,0x2b,0x0b,0x19,0x89,0x0b,0x93,0x2d, + 0xd8,0x6a,0x13,0x29,0xc8,0x4a,0x83,0x0d,0x98,0x2a,0x03,0x09,0x88,0x0a,0x9a,0x3c, + 0x59,0x69,0x1a,0x38,0x49,0x49,0x8a,0x1c,0x19,0x29,0x0a,0x18,0x09,0x09,0x92,0x2c, + 0x58,0x68,0x12,0x28,0x48,0x48,0x82,0x0c,0x18,0x28,0x02,0x08,0x08,0x08,0xd9,0x75, + 0xd3,0x67,0x59,0x71,0xc3,0x47,0xc9,0x55,0x93,0x27,0x49,0x51,0x83,0x07,0xd1,0x65, + 0xd2,0x66,0x51,0x61,0xc2,0x46,0xc1,0x45,0x92,0x26,0x41,0x41,0x82,0x06,0xd8,0x74, + 0x53,0x65,0x58,0x70,0x43,0x45,0xc8,0x54,0x13,0x25,0x48,0x50,0x03,0x05,0xd0,0x64, + 0x52,0x64,0x50,0x60,0x42,0x44,0xc0,0x44,0x12,0x24,0x40,0x40,0x02,0x04,0x99,0x35, + 0xd1,0x63,0x19,0x31,0xc1,0x43,0x89,0x15,0x91,0x23,0x09,0x11,0x81,0x03,0x91,0x25, + 0xd0,0x62,0x11,0x21,0xc0,0x42,0x81,0x05,0x90,0x22,0x01,0x01,0x80,0x02,0x98,0x34, + 0x51,0x61,0x18,0x30,0x41,0x41,0x88,0x14,0x11,0x21,0x08,0x10,0x01,0x01,0x90,0x24, + 0x50,0x60,0x10,0x20,0x40,0x40,0x80,0x04,0x10,0x20,0x00,0x00,0x00,0x00,0xff,0xff, + 0xff,0xff,0x7f,0xfb,0xef,0xdf,0xef,0xdf,0xbf,0xbf,0x6f,0xdb,0xaf,0x9f,0xf7,0xef, + 0xfe,0xfe,0x77,0xeb,0xee,0xde,0xe7,0xcf,0xbe,0xbe,0x67,0xcb,0xae,0x9e,0xfe,0xfe, + 0x7f,0xfd,0x7e,0xfa,0x6f,0xdd,0xee,0xde,0x3f,0xbd,0x6e,0xda,0x2f,0x9d,0xf6,0xee, + 0x7e,0xfc,0x76,0xea,0x6e,0xdc,0xe6,0xce,0x3e,0xbc,0x66,0xca,0x2e,0x9c,0xbf,0xbf, + 0xfd,0xfb,0x3f,0xbb,0xed,0xdb,0xaf,0x9f,0xbd,0xbb,0x2f,0x9b,0xad,0x9b,0xb7,0xaf, + 0xfc,0xfa,0x37,0xab,0xec,0xda,0xa7,0x8f,0xbc,0xba,0x27,0x8b,0xac,0x9a,0xbe,0xbe, + 0x7d,0xf9,0x3e,0xba,0x6d,0xd9,0xae,0x9e,0x3d,0xb9,0x2e,0x9a,0x2d,0x99,0xb6,0xae, + 0x7c,0xf8,0x36,0xaa,0x6c,0xd8,0xa6,0x8e,0x3c,0xb8,0x26,0x8a,0x2c,0x98,0xfd,0xf7, + 0xf7,0xf7,0x7d,0xf3,0xe7,0xd7,0xed,0xd7,0xb7,0xb7,0x6d,0xd3,0xa7,0x97,0xf5,0xe7, + 0xf6,0xf6,0x75,0xe3,0xe6,0xd6,0xe5,0xc7,0xb6,0xb6,0x65,0xc3,0xa6,0x96,0xfc,0xf6, + 0x77,0xf5,0x7c,0xf2,0x67,0xd5,0xec,0xd6,0x37,0xb5,0x6c,0xd2,0x27,0x95,0xf4,0xe6, + 0x76,0xf4,0x74,0xe2,0x66,0xd4,0xe4,0xc6,0x36,0xb4,0x64,0xc2,0x26,0x94,0xbd,0xb7, + 0xf5,0xf3,0x3d,0xb3,0xe5,0xd3,0xad,0x97,0xb5,0xb3,0x2d,0x93,0xa5,0x93,0xb5,0xa7, + 0xf4,0xf2,0x35,0xa3,0xe4,0xd2,0xa5,0x87,0xb4,0xb2,0x25,0x83,0xa4,0x92,0xbc,0xb6, + 0x75,0xf1,0x3c,0xb2,0x65,0xd1,0xac,0x96,0x35,0xb1,0x2c,0x92,0x25,0x91,0xb4,0xa6, + 0x74,0xf0,0x34,0xa2,0x64,0xd0,0xa4,0x86,0x34,0xb0,0x24,0x82,0x24,0x90,0xfb,0x7f, + 0xdf,0xef,0x7b,0x7b,0xcf,0xcf,0xeb,0x5f,0x9f,0xaf,0x6b,0x5b,0x8f,0x8f,0xf3,0x6f, + 0xde,0xee,0x73,0x6b,0xce,0xce,0xe3,0x4f,0x9e,0xae,0x63,0x4b,0x8e,0x8e,0xfa,0x7e, + 0x5f,0xed,0x7a,0x7a,0x4f,0xcd,0xea,0x5e,0x1f,0xad,0x6a,0x5a,0x0f,0x8d,0xf2,0x6e, + 0x5e,0xec,0x72,0x6a,0x4e,0xcc,0xe2,0x4e,0x1e,0xac,0x62,0x4a,0x0e,0x8c,0xbb,0x3f, + 0xdd,0xeb,0x3b,0x3b,0xcd,0xcb,0xab,0x1f,0x9d,0xab,0x2b,0x1b,0x8d,0x8b,0xb3,0x2f, + 0xdc,0xea,0x33,0x2b,0xcc,0xca,0xa3,0x0f,0x9c,0xaa,0x23,0x0b,0x8c,0x8a,0xba,0x3e, + 0x5d,0xe9,0x3a,0x3a,0x4d,0xc9,0xaa,0x1e,0x1d,0xa9,0x2a,0x1a,0x0d,0x89,0xb2,0x2e, + 0x5c,0xe8,0x32,0x2a,0x4c,0xc8,0xa2,0x0e,0x1c,0xa8,0x22,0x0a,0x0c,0x88,0xf9,0x77, + 0xd7,0xe7,0x79,0x73,0xc7,0xc7,0xe9,0x57,0x97,0xa7,0x69,0x53,0x87,0x87,0xf1,0x67, + 0xd6,0xe6,0x71,0x63,0xc6,0xc6,0xe1,0x47,0x96,0xa6,0x61,0x43,0x86,0x86,0xf8,0x76, + 0x57,0xe5,0x78,0x72,0x47,0xc5,0xe8,0x56,0x17,0xa5,0x68,0x52,0x07,0x85,0xf0,0x66, + 0x56,0xe4,0x70,0x62,0x46,0xc4,0xe0,0x46,0x16,0xa4,0x60,0x42,0x06,0x84,0xb9,0x37, + 0xd5,0xe3,0x39,0x33,0xc5,0xc3,0xa9,0x17,0x95,0xa3,0x29,0x13,0x85,0x83,0xb1,0x27, + 0xd4,0xe2,0x31,0x23,0xc4,0xc2,0xa1,0x07,0x94,0xa2,0x21,0x03,0x84,0x82,0xb8,0x36, + 0x55,0xe1,0x38,0x32,0x45,0xc1,0xa8,0x16,0x15,0xa1,0x28,0x12,0x05,0x81,0xb0,0x26, + 0x54,0xe0,0x30,0x22,0x44,0xc0,0xa0,0x06,0x14,0xa0,0x20,0x02,0x04,0x80,0xdf,0xfd, + 0xfb,0x7f,0x5f,0xf9,0xeb,0x5f,0xcf,0xdd,0xbb,0x3f,0x4f,0xd9,0xab,0x1f,0xd7,0xed, + 0xfa,0x7e,0x57,0xe9,0xea,0x5e,0xc7,0xcd,0xba,0x3e,0x47,0xc9,0xaa,0x1e,0xde,0xfc, + 0x7b,0x7d,0x5e,0xf8,0x6b,0x5d,0xce,0xdc,0x3b,0x3d,0x4e,0xd8,0x2b,0x1d,0xd6,0xec, + 0x7a,0x7c,0x56,0xe8,0x6a,0x5c,0xc6,0xcc,0x3a,0x3c,0x46,0xc8,0x2a,0x1c,0x9f,0xbd, + 0xf9,0x7b,0x1f,0xb9,0xe9,0x5b,0x8f,0x9d,0xb9,0x3b,0x0f,0x99,0xa9,0x1b,0x97,0xad, + 0xf8,0x7a,0x17,0xa9,0xe8,0x5a,0x87,0x8d,0xb8,0x3a,0x07,0x89,0xa8,0x1a,0x9e,0xbc, + 0x79,0x79,0x1e,0xb8,0x69,0x59,0x8e,0x9c,0x39,0x39,0x0e,0x98,0x29,0x19,0x96,0xac, + 0x78,0x78,0x16,0xa8,0x68,0x58,0x86,0x8c,0x38,0x38,0x06,0x88,0x28,0x18,0xdd,0xf5, + 0xf3,0x77,0x5d,0xf1,0xe3,0x57,0xcd,0xd5,0xb3,0x37,0x4d,0xd1,0xa3,0x17,0xd5,0xe5, + 0xf2,0x76,0x55,0xe1,0xe2,0x56,0xc5,0xc5,0xb2,0x36,0x45,0xc1,0xa2,0x16,0xdc,0xf4, + 0x73,0x75,0x5c,0xf0,0x63,0x55,0xcc,0xd4,0x33,0x35,0x4c,0xd0,0x23,0x15,0xd4,0xe4, + 0x72,0x74,0x54,0xe0,0x62,0x54,0xc4,0xc4,0x32,0x34,0x44,0xc0,0x22,0x14,0x9d,0xb5, + 0xf1,0x73,0x1d,0xb1,0xe1,0x53,0x8d,0x95,0xb1,0x33,0x0d,0x91,0xa1,0x13,0x95,0xa5, + 0xf0,0x72,0x15,0xa1,0xe0,0x52,0x85,0x85,0xb0,0x32,0x05,0x81,0xa0,0x12,0x9c,0xb4, + 0x71,0x71,0x1c,0xb0,0x61,0x51,0x8c,0x94,0x31,0x31,0x0c,0x90,0x21,0x11,0x94,0xa4, + 0x70,0x70,0x14,0xa0,0x60,0x50,0x84,0x84,0x30,0x30,0x04,0x80,0x20,0x10,0xdb,0x7d, + 0xdb,0x6f,0x5b,0x79,0xcb,0x4f,0xcb,0x5d,0x9b,0x2f,0x4b,0x59,0x8b,0x0f,0xd3,0x6d, + 0xda,0x6e,0x53,0x69,0xca,0x4e,0xc3,0x4d,0x9a,0x2e,0x43,0x49,0x8a,0x0e,0xda,0x7c, + 0x5b,0x6d,0x5a,0x78,0x4b,0x4d,0xca,0x5c,0x1b,0x2d,0x4a,0x58,0x0b,0x0d,0xd2,0x6c, + 0x5a,0x6c,0x52,0x68,0x4a,0x4c,0xc2,0x4c,0x1a,0x2c,0x42,0x48,0x0a,0x0c,0x9b,0x3d, + 0xd9,0x6b,0x1b,0x39,0xc9,0x4b,0x8b,0x1d,0x99,0x2b,0x0b,0x19,0x89,0x0b,0x93,0x2d, + 0xd8,0x6a,0x13,0x29,0xc8,0x4a,0x83,0x0d,0x98,0x2a,0x03,0x09,0x88,0x0a,0x9a,0x3c, + 0x59,0x69,0x1a,0x38,0x49,0x49,0x8a,0x1c,0x19,0x29,0x0a,0x18,0x09,0x09,0x92,0x2c, + 0x58,0x68,0x12,0x28,0x48,0x48,0x82,0x0c,0x18,0x28,0x02,0x08,0x08,0x08,0xd9,0x75, + 0xd3,0x67,0x59,0x71,0xc3,0x47,0xc9,0x55,0x93,0x27,0x49,0x51,0x83,0x07,0xd1,0x65, + 0xd2,0x66,0x51,0x61,0xc2,0x46,0xc1,0x45,0x92,0x26,0x41,0x41,0x82,0x06,0xd8,0x74, + 0x53,0x65,0x58,0x70,0x43,0x45,0xc8,0x54,0x13,0x25,0x48,0x50,0x03,0x05,0xd0,0x64, + 0x52,0x64,0x50,0x60,0x42,0x44,0xc0,0x44,0x12,0x24,0x40,0x40,0x02,0x04,0x99,0x35, + 0xd1,0x63,0x19,0x31,0xc1,0x43,0x89,0x15,0x91,0x23,0x09,0x11,0x81,0x03,0x91,0x25, + 0xd0,0x62,0x11,0x21,0xc0,0x42,0x81,0x05,0x90,0x22,0x01,0x01,0x80,0x02,0x98,0x34, + 0x51,0x61,0x18,0x30,0x41,0x41,0x88,0x14,0x11,0x21,0x08,0x10,0x01,0x01,0x90,0x24, + 0x50,0x60,0x10,0x20,0x40,0x40,0x80,0x04,0x10,0x20,0x00,0x00,0x68,0xf7,0x80,0x0c, + 0xcc,0x40,0x3b,0xa1,0xe7,0xdd,0x4e,0xb6,0x98,0xeb,0xa8,0xdb,0xa5,0x03,0xbf,0x11, + 0x8c,0x0d,0x33,0xa5,0x1f,0x8e,0x7e,0xc1,0x83,0xc1,0xe6,0xa4,0xa4,0xc2,0x04,0x19, + 0x0f,0x00,0x97,0x95,0x7b,0xa0,0xf7,0x67,0x21,0xed,0x6a,0x5a,0xb8,0xe0,0x61,0x6e, + 0xc2,0x63,0x4d,0x17,0x9f,0x8e,0x67,0xaf,0x2a,0xb5,0x5d,0xc6,0xdf,0x67,0x1e,0x4f, + 0x46,0x4a,0x6c,0x06,0x91,0xd0,0x76,0x4c,0x0c,0xe9,0xe8,0x9b,0xa7,0x07,0x6e,0xef, + 0xfc,0xa1,0x17,0x54,0x93,0x65,0x6a,0x4e,0xe0,0xe4,0xa6,0xf9,0xa6,0xe6,0x20,0xe1, + 0x54,0xb9,0x81,0xe5,0x82,0xa6,0x43,0x90,0x61,0x06,0x2a,0x1a,0xb2,0x6a,0xba,0xaf, + 0x4b,0xb0,0x16,0x54,0x4f,0x45,0x1b,0x82,0x81,0x9a,0x7f,0x86,0xc5,0x63,0x1a,0x05, + 0x6b,0x68,0xd4,0x3d,0xb9,0xd7,0x4c,0xb3,0x58,0xe7,0x56,0x5f,0x32,0xc9,0xf1,0x47, + 0x4a,0x96,0x35,0x2d,0x5b,0x86,0x44,0x0f,0xc8,0xe6,0x4e,0xc2,0xa4,0xc8,0x94,0xf6, + 0x69,0xd9,0xbd,0xbd,0xb6,0xf5,0x70,0xd8,0x2c,0xfe,0xab,0xd2,0x31,0xe9,0xa4,0xdb, + 0x0a,0x4d,0xc9,0x63,0xf3,0x49,0x2d,0xc8,0x29,0x0b,0xd9,0xce,0x9b,0xb6,0x3d,0x5b, + 0xf8,0x93,0x92,0x40,0x5a,0xd7,0x04,0xed,0xa1,0x2e,0x91,0x53,0x58,0xb7,0x28,0x58, + 0x08,0x6d,0xce,0x43,0x59,0x86,0x3c,0x1a,0xbc,0xb0,0xda,0xf8,0x47,0xee,0x76,0xc1, + 0x33,0x60,0x43,0x4f,0x9e,0xd5,0xe4,0xe5,0x37,0x2d,0xd3,0x56,0xba,0xf5,0xcb,0x5d, + 0x16,0x5a,0x0b,0x59,0x72,0x6d,0x4d,0x1b,0x34,0x92,0x64,0x4c,0x7a,0x90,0x12,0x78, + 0x20,0x52,0x84,0xbf,0x58,0xab,0xcb,0xa1,0xbc,0x52,0x2b,0x01,0xba,0x7d,0x34,0x6f, + 0xd4,0x72,0x33,0x7c,0x35,0x5d,0x7a,0x39,0x62,0x31,0x63,0xca,0x5f,0xae,0x80,0x31, + 0x5d,0xb3,0x85,0x01,0xac,0xb1,0xc8,0xa5,0x5d,0x3c,0x6e,0xda,0x98,0x7f,0x22,0xee, + 0x78,0x8c,0x59,0xcb,0x9f,0xef,0x9d,0xb5,0x0e,0xfe,0x22,0x84,0xf7,0xdc,0x7a,0x55, + 0xad,0x92,0xa2,0xf9,0x33,0x54,0x0a,0x0f,0x70,0x06,0x6f,0x55,0x64,0xdb,0xdc,0xb0, + 0x21,0xb1,0x98,0x74,0x92,0x17,0xdc,0xf4,0x25,0xf8,0xe2,0x74,0xfe,0xd3,0x45,0x81, + 0xc0,0xbb,0x45,0xd4,0xd8,0x9b,0xd5,0xe5,0xca,0x64,0x14,0xe1,0xb2,0x7c,0x8d,0xd7, + 0x6b,0x35,0x93,0x44,0x21,0x9c,0x9b,0x36,0x21,0x57,0x8d,0xb5,0xff,0x37,0x56,0x80, + 0x64,0xa5,0xef,0x67,0x50,0xfa,0xc6,0x08,0xc9,0xf8,0x56,0xd2,0x12,0x5a,0xda,0x62, + 0xc0,0xa8,0xc8,0x6f,0x73,0x9d,0x9a,0xca,0x82,0x0b,0x58,0x82,0x33,0x8c,0x11,0xeb, + 0x53,0x87,0xf9,0x19,0x4d,0x99,0x49,0x25,0xe0,0x5e,0xe9,0x2c,0x30,0x2b,0x25,0x49, + 0x0a,0x93,0xdf,0x15,0x9b,0x4b,0xa2,0xc9,0xed,0x50,0x5d,0xa3,0x3f,0x8f,0xe2,0xbb, + 0xdf,0xb8,0x04,0x4e,0x51,0xde,0x5e,0xc9,0x83,0x1d,0xd0,0x40,0x93,0x5f,0xc4,0xda, + 0x73,0xb9,0x90,0x55,0x99,0x39,0xfe,0xeb,0x61,0x39,0x98,0x76,0x10,0xbf,0xf8,0x2b, + 0xac,0x6e,0xc3,0x3c,0xa8,0x28,0x4f,0x69,0x22,0x1c,0x87,0x8f,0xf0,0xd5,0x8f,0xdf, + 0x63,0x3d,0x48,0x2c,0xf1,0x29,0x61,0x87,0x23,0xa2,0xb7,0x0c,0xb5,0x5f,0x97,0x26, + 0x22,0xc0,0xde,0x83,0xfd,0x43,0x98,0xa8,0x94,0x54,0xe6,0xa3,0xbf,0x82,0x9f,0x13, + 0x88,0x8d,0x7a,0xb3,0xe2,0x5c,0xb8,0xf4,0xd7,0xc2,0x47,0x45,0x33,0x82,0x21,0x27, + 0x0b,0x80,0xb7,0x65,0x6b,0x0f,0x16,0x38,0xaf,0xb6,0x8f,0x92,0xbc,0xef,0x41,0xe2, + 0x8f,0x67,0xbf,0x87,0x7e,0x21,0xda,0xc8,0xe7,0xd3,0x42,0x48,0xbd,0x61,0x76,0x2c, + 0x89,0x02,0x0c,0xd5,0x18,0xae,0xa4,0x9c,0xbb,0x65,0x4b,0xc3,0xa1,0x19,0xe8,0x05, + 0x6c,0xfa,0xd6,0xf2,0x36,0x05,0x2e,0xf7,0xac,0xe7,0x43,0xc6,0x9b,0x4a,0x61,0x83, + 0x8a,0xc6,0x65,0x43,0xde,0xf5,0x33,0x90,0xc0,0x1b,0xe3,0x25,0x3d,0x94,0xed,0xa2, + 0x38,0x84,0xb7,0xcf,0x9f,0xa3,0x91,0x6e,0xe5,0x11,0x38,0x48,0x85,0x1a,0x7c,0x8e, + 0x8d,0x23,0x19,0xbf,0x12,0x07,0x30,0xd7,0x4c,0xcc,0xcc,0xbe,0xa9,0x4b,0x02,0x5c, + 0x51,0x7c,0xe8,0x9a,0x19,0x89,0x7f,0x9a,0x59,0x49,0xfe,0x2d,0x1f,0xab,0xe7,0x1c, + 0xe7,0x08,0x67,0xfc,0x96,0x0e,0xb3,0xd6,0xc4,0x3e,0x77,0xdc,0xd2,0x45,0xbd,0xe7, + 0x8d,0x3e,0x58,0x20,0xf1,0x70,0xe4,0x3f,0x4d,0x8b,0x13,0x22,0x21,0xb9,0xca,0xc0, + 0x65,0x18,0x66,0x3c,0xf5,0x3e,0x0d,0xca,0xfd,0x73,0x26,0xfd,0xff,0x33,0x34,0x55, + 0x4b,0xc3,0xf2,0x5b,0x1b,0xcd,0x89,0x04,0x87,0x7a,0x41,0xdb,0xa8,0x10,0x63,0xba, + 0x56,0xce,0xdd,0xcb,0xff,0xee,0x55,0xd4,0x33,0x6a,0x4c,0x5e,0x7f,0x11,0x0a,0xfb, + 0xd3,0x16,0xc2,0x2c,0x9d,0xc3,0x44,0x68,0x3d,0x52,0xed,0xf2,0x34,0x9d,0x25,0x71, + 0xee,0x3b,0xa5,0x77,0x3a,0x54,0x7f,0x53,0x2e,0x64,0x52,0xd4,0x9f,0x56,0x0b,0x63, + 0xc9,0x9d,0x79,0x67,0x3b,0x55,0xab,0x3a,0x47,0xa1,0x5f,0xa9,0xab,0x5e,0x42,0x8b, + 0xcf,0x57,0xfb,0x17,0x35,0xb6,0x6b,0x37,0x65,0x76,0xeb,0x35,0xf0,0x26,0x73,0xa0, + 0x25,0x38,0xf3,0x07,0x34,0x1e,0x6b,0xc0,0x8f,0x7b,0xda,0x46,0x27,0xb3,0xc0,0xb1, + 0xd3,0x9b,0xba,0x52,0x34,0x1f,0x0c,0x66,0x7a,0x1c,0xaa,0x6e,0xe4,0x5f,0x2a,0x47, + 0xce,0x97,0x8d,0x27,0x2d,0xb6,0xdc,0xe1,0x6d,0xb1,0xa2,0x67,0xe5,0x5e,0xd1,0xb0, + 0x5b,0x99,0x23,0xc6,0xdd,0xa4,0x55,0xfa,0x2e,0x94,0xb0,0x05,0x76,0x06,0x33,0x31, + 0xa3,0x12,0xbd,0xda,0x93,0x1a,0x43,0x8d,0x44,0xb2,0x3f,0x37,0x9c,0x15,0x14,0x9a, + 0xa9,0x8e,0xf0,0xdf,0x5e,0xb3,0x64,0x4a,0x3e,0x2d,0xc8,0x98,0x97,0x1d,0x70,0x95, + 0x7f,0xd7,0x99,0xa3,0xce,0xfb,0x45,0x3e,0x71,0x5a,0x8c,0xf8,0xef,0x56,0x04,0x91, + 0x74,0x2e,0xe4,0xb0,0xdc,0x65,0x25,0x55,0x14,0xd9,0xe9,0x9c,0xec,0x55,0x4e,0x3b, + 0x7b,0x24,0x2a,0x2f,0x40,0x1a,0x80,0x8a,0x4c,0x24,0x9c,0x4e,0x25,0xbb,0xd5,0x28, + 0x46,0xde,0xa6,0xff,0x1c,0x43,0x48,0x95,0xcd,0xae,0xf2,0x1f,0x6c,0xea,0x2a,0x29, + 0x25,0xc0,0xfc,0x26,0x3f,0xff,0x16,0x7c,0x93,0x9c,0x7b,0x62,0x83,0xff,0x19,0x4f, + 0x5b,0x3d,0xdd,0x6a,0x49,0x0b,0xf7,0xeb,0x2b,0xd0,0xa9,0x66,0xdd,0xfd,0x71,0xea, + 0x8c,0x0e,0x6a,0x6f,0x42,0x1e,0x93,0x7b,0x13,0xff,0x24,0xff,0x07,0x7e,0x5b,0x00, + 0x06,0x70,0x7f,0xa1,0xda,0x2d,0x75,0xce,0xd9,0xbd,0x55,0x57,0x7a,0x63,0xf7,0x6e, + 0x2f,0xde,0x77,0x6a,0x3f,0xfe,0x9a,0xdd,0x49,0x1a,0x47,0xb6,0xd1,0xe1,0x53,0x7e, + 0xe8,0x0f,0x7a,0x7a,0xf8,0x2f,0x3c,0xcc,0xc8,0x46,0xa9,0x31,0xa7,0x74,0xb6,0x21, + 0x00,0xac,0x36,0x24,0xd7,0x8c,0x7c,0xd8,0xc2,0x37,0x42,0xbf,0xae,0x61,0xc0,0x07, + 0x2c,0xd8,0x82,0xb7,0x50,0xaf,0x94,0x5a,0x2a,0xd9,0x11,0x7e,0x39,0x06,0x5a,0x02, + 0xe8,0xe7,0x0e,0x26,0x79,0xe7,0xdc,0x74,0x0f,0x04,0x18,0x68,0x38,0x57,0x95,0x1f, + 0x11,0x39,0xc0,0x74,0xdc,0x89,0xbd,0xf3,0xc2,0x4c,0xd5,0x67,0xe2,0xcd,0xf2,0xe1, + 0x5b,0xa8,0xb7,0xc1,0x5b,0x85,0x7f,0xf9,0x05,0xe3,0xea,0x84,0xc5,0x32,0xc7,0x76, + 0x6a,0xec,0x40,0x72,0x72,0x8a,0x55,0x26,0x1e,0x7c,0x31,0xbc,0x84,0xca,0x34,0x98, + 0x61,0xf8,0xcf,0xef,0x03,0xf4,0xd9,0x13,0x17,0x0b,0x5c,0x7e,0xd9,0xc2,0x7d,0x85, + 0x08,0x0b,0xfd,0x9c,0x65,0x8b,0xd4,0x06,0x92,0x1f,0xcd,0xb9,0x00,0xc1,0xf4,0x6b, + 0xa7,0xd4,0xdd,0x95,0x72,0x39,0x9e,0xb4,0x36,0x28,0xec,0x38,0xc7,0xc6,0x80,0x3b, + 0x2c,0x0f,0x62,0x5f,0x58,0x48,0x17,0xff,0x21,0xea,0x8c,0xe9,0x52,0x68,0x4b,0xb5, + 0x03,0x56,0xf2,0xaf,0x15,0x2e,0x7c,0xfc,0x9d,0xe9,0x84,0xf5,0xab,0xc6,0x7b,0x68, + 0xa8,0x9e,0xfb,0xbe,0x9c,0x4b,0x57,0x98,0x08,0x6e,0x12,0x9c,0xdc,0x9e,0x2e,0xb0, + 0x88,0x0b,0x28,0xa6,0xc9,0x6f,0x9f,0xe6,0xa0,0xf9,0x1a,0x2b,0xb0,0x0d,0x12,0xe2, + 0xdf,0xcd,0xc4,0xbb,0x38,0x5c,0x50,0xd3,0x6a,0x3e,0xac,0xb0,0x07,0x66,0xc9,0x63, + 0x3f,0xcc,0xab,0x15,0xcc,0xb0,0x3a,0x24,0xe5,0xf5,0x47,0x3e,0x0e,0x7b,0xd1,0x7f, + 0x5d,0xb3,0xad,0x47,0x6c,0x30,0x77,0xa1,0xe1,0xeb,0x4a,0x67,0x70,0xf2,0x5b,0x1d, + 0x4a,0x41,0xcd,0x66,0xab,0xbe,0x5b,0xb6,0x40,0x8c,0x3e,0x25,0x2d,0xd1,0x16,0x4b, + 0x95,0x28,0x06,0xc5,0x59,0xd6,0x0a,0xfa,0x62,0xf0,0x2f,0xc3,0xd3,0x8b,0x6c,0xc4, + 0x1c,0x35,0xec,0xc9,0x58,0xb7,0xde,0x36,0xf1,0x51,0xe9,0x7c,0x75,0x05,0xfa,0x8a, + 0x9d,0x36,0xa4,0x34,0xa0,0x31,0xc3,0xfa,0x89,0x22,0x60,0x71,0x46,0x94,0x94,0x5a, + 0x98,0x1d,0xac,0x24,0xf9,0x35,0x5a,0xb7,0x71,0xfc,0x96,0x0e,0x03,0x78,0x38,0x2c, + 0x0a,0x15,0xd4,0x07,0xd3,0x2a,0xa2,0xca,0x97,0x2d,0xa8,0x34,0x8c,0x0a,0xd3,0x99, + 0x1e,0x2f,0x8e,0x9e,0x3d,0xc2,0x5b,0x3c,0x75,0xc3,0x35,0x19,0xac,0x67,0x13,0x29, + 0xf8,0x0a,0xd7,0x85,0xf8,0xc1,0xd1,0x87,0xfa,0x6f,0xce,0xa9,0x75,0x19,0x52,0x59, + 0x29,0xcb,0x0f,0x82,0xaf,0xce,0x60,0x83,0x4a,0x19,0xe2,0x8d,0x78,0xd4,0xe3,0x51, + 0xbe,0xce,0x98,0x58,0x32,0x97,0x75,0xe8,0xa2,0xbd,0x16,0xf4,0x29,0xd8,0xff,0x44, + 0x93,0xef,0x9e,0xaf,0x39,0xbf,0xb6,0x72,0x08,0x7d,0x7a,0x82,0xd8,0x18,0x62,0x54, + 0x16,0xac,0x01,0x47,0xd1,0x2c,0x70,0x18,0x76,0xbe,0x16,0xeb,0x32,0x4c,0x8f,0xd4, + 0xb5,0xe0,0xd7,0x50,0xf9,0x36,0x49,0x64,0x00,0xad,0x60,0x1f,0x98,0x3f,0x17,0x32, + 0x77,0x80,0x9e,0x96,0x7f,0xaf,0x56,0x40,0xb3,0x3d,0xe4,0x86,0xf5,0x20,0x3e,0x70, + 0xfa,0x5c,0xbe,0x9b,0xfe,0xd3,0xec,0xcc,0xb8,0x60,0x98,0x26,0x22,0xf7,0xe1,0x0e, + 0xe6,0x7f,0x21,0x35,0x60,0xad,0x27,0x41,0x3b,0x1f,0x6a,0xad,0xab,0xe5,0xfd,0xed, + 0x78,0x02,0x12,0xa6,0x83,0x0c,0xfb,0xc0,0x83,0x1e,0x66,0x97,0x01,0x61,0xe3,0x31, + 0x3a,0x05,0x62,0x41,0x4c,0xe4,0x71,0x10,0xad,0x52,0x70,0x64,0x06,0x4f,0x0d,0xbc, + 0x9e,0x78,0x08,0x69,0x33,0xcb,0xbe,0x45,0x2c,0x60,0xcb,0x87,0x41,0xf9,0x29,0xbc, + 0x67,0x05,0xe7,0xb6,0x15,0xa8,0x57,0xf7,0x22,0x62,0x31,0x7a,0xbd,0xd4,0x44,0xbe, + 0x8f,0xf3,0xa9,0x68,0x9f,0xcb,0x59,0x00,0xaf,0x6c,0xa7,0xf2,0xd3,0x6a,0x0a,0xf9, + 0x12,0x55,0x63,0x9f,0x16,0xac,0x64,0xbb,0xa7,0x6a,0x15,0xbf,0x37,0x2a,0x9d,0x82, + 0xf0,0xea,0x2e,0x82,0x9e,0xa7,0x7f,0x44,0x27,0xdb,0x9a,0xeb,0xa7,0xa9,0x71,0x1c, + 0x67,0xd8,0x80,0x9e,0x9a,0xea,0x8c,0x1a,0xd6,0x65,0x94,0xde,0x92,0x66,0x4d,0x79, + 0x7a,0x76,0x4b,0x20,0xb9,0xc5,0x45,0xb3,0x05,0x9a,0x2e,0x4c,0xf7,0xe8,0x25,0x44, + 0x58,0xb8,0xca,0x8c,0xc2,0xae,0x0a,0x62,0xae,0x63,0x8c,0xef,0xb7,0xce,0x69,0xda, + 0xe6,0xfc,0xae,0xaf,0x5d,0xbb,0x38,0x09,0x45,0xcc,0xb2,0x6d,0x15,0xa9,0xa4,0x49, + 0xd0,0x8d,0xdd,0xee,0xbc,0xa3,0x41,0x18,0xcc,0xc5,0x5f,0xfc,0xd8,0xe4,0x79,0x9b, + 0x70,0x02,0xb5,0xce,0x1d,0x04,0x43,0x66,0x4a,0xd9,0xdd,0xef,0x53,0xe2,0x1a,0xaf, + 0x44,0x9a,0x32,0x7a,0x34,0x05,0x37,0x7a,0xac,0xa2,0x72,0xd8,0x16,0x44,0xd5,0xd9, + 0xd8,0xad,0x29,0x26,0xc8,0x10,0x87,0x50,0xc9,0x2c,0x82,0x17,0x57,0xfc,0xda,0xf1, + 0xc6,0xa4,0xb3,0x7f,0xb4,0xf0,0x95,0xb0,0xf2,0xb6,0xcb,0x33,0x74,0xc3,0xf0,0x92, + 0x39,0x21,0x95,0x64,0xe7,0x6e,0x45,0x43,0xed,0x72,0x3f,0x4b,0x67,0x08,0xb0,0x51, + 0x87,0x4b,0x76,0x56,0x17,0x97,0x4e,0x53,0x30,0x7b,0xe2,0x77,0x9d,0x56,0xd7,0x77, + 0xd0,0x68,0xee,0x36,0x76,0x1e,0x49,0x6f,0x61,0xa5,0xbe,0x06,0x73,0x54,0xda,0xf2, + 0x07,0x69,0xa7,0xa7,0xc4,0x37,0xb6,0xcc,0xbc,0x89,0xcf,0x56,0xb4,0x59,0x7b,0x42, + 0x4c,0x35,0x2d,0xcb,0xdc,0x85,0xb8,0x0c,0xc9,0x71,0xbc,0x04,0xe5,0x7a,0x87,0x16, + 0xb4,0x6a,0x72,0x7d,0x22,0x03,0xf1,0x59,0x32,0x55,0xce,0xac,0x3c,0x23,0x6e,0xe9, + 0x11,0x18,0x6f,0x5e,0x31,0xf9,0x8b,0x23,0xda,0xec,0xfc,0xa1,0x37,0x54,0x07,0x16, + 0x8e,0x0a,0xa5,0xf4,0x33,0x1c,0x61,0x37,0x07,0x08,0xd6,0x52,0xdf,0x2e,0x67,0x64, + 0x4c,0x18,0x29,0xab,0x47,0x3b,0xf8,0x3f,0xf1,0xa9,0xfc,0x81,0xe3,0xe0,0xdd,0x7b, + 0x6c,0x33,0xd5,0x3f,0x28,0xb7,0x4e,0x14,0x93,0x7d,0xa0,0x7b,0x95,0x1e,0x10,0xdd, + 0x8e,0x32,0x3c,0x2f,0x39,0x4d,0x85,0x85,0x07,0x7f,0x7e,0xcc,0x8b,0xf2,0x25,0xd8, + 0xe4,0xda,0xb9,0x4a,0xb6,0xba,0x4f,0x14,0x1b,0xbd,0xc9,0x6a,0x95,0xf1,0xaf,0xfc, + 0x0e,0x30,0xb1,0x56,0x4f,0x14,0x01,0x6a,0x1a,0x7c,0xe9,0x73,0x14,0xad,0xbb,0xb1, + 0x1a,0xaf,0x9a,0x00,0x31,0x40,0x06,0xb8,0xab,0xd2,0x38,0x3c,0xd2,0x56,0x3d,0x63, + 0x03,0x88,0xe0,0x92,0xed,0x60,0xdd,0x43,0x7d,0xe0,0x9a,0xf2,0x45,0x65,0x44,0x10, + 0x8a,0x06,0x01,0x0d,0x9e,0x2c,0xaa,0x90,0xde,0xed,0xd9,0x47,0xf2,0xaf,0x0b,0x71, + 0x8d,0x43,0xa1,0x77,0x10,0x2c,0x0a,0xc2,0xc7,0xce,0x19,0x73,0xc5,0x65,0x10,0x5f, + 0x6e,0x1f,0xfa,0xc3,0xbe,0x38,0x38,0x67,0xc1,0x4b,0x34,0x97,0xf1,0xef,0xd1,0xb8, + 0xbc,0x48,0xe6,0x53,0x86,0x2a,0xef,0x98,0xbc,0xc8,0x3f,0x87,0xf0,0x38,0x39,0x33, + 0x25,0x02,0xef,0x43,0x03,0x7a,0x39,0x03,0xe4,0x0a,0xd5,0xe2,0xf6,0x1b,0x37,0xf4, + 0x91,0x4a,0x7d,0x1f,0x5a,0x63,0xa3,0xbb,0x38,0xec,0x3a,0x31,0x70,0x5a,0x07,0x1d, + 0xf3,0xb5,0xaa,0x0b,0x99,0x6c,0x6c,0xa9,0xa1,0x6a,0xf7,0xec,0xf9,0xe2,0x39,0xe9, + 0x5f,0x18,0x8b,0x9e,0x18,0xd6,0x04,0x4b,0x6d,0x42,0x41,0x28,0x22,0x6f,0x5b,0x45, + 0xe3,0xb8,0xab,0xcf,0xf3,0x24,0xbf,0xba,0xce,0x40,0x44,0xcf,0xa7,0x6a,0x55,0x94, + 0x79,0xa0,0xb3,0x3d,0x38,0x4b,0xdd,0x2a,0x9b,0x0f,0xc0,0x3d,0x5b,0x23,0xbd,0xe8, + 0xe7,0x8c,0xeb,0x02,0xd3,0x48,0x62,0x37,0x21,0x78,0xb5,0x28,0xf9,0x71,0x91,0x58, + 0xdf,0x4c,0x74,0x5e,0xed,0x5a,0xda,0x74,0x8c,0x0d,0x36,0xfc,0xa7,0x4d,0x98,0x48, + 0x0a,0x4e,0x6a,0x92,0x23,0xf0,0x53,0x98,0x42,0xb1,0xb0,0x3c,0x79,0x2f,0xf4,0xf9, + 0x6e,0x8f,0xcf,0x49,0x03,0x6b,0x58,0x78,0x2a,0x29,0x77,0x3f,0x58,0xbb,0x41,0x1f, + 0x4b,0x42,0x3c,0x77,0x58,0x22,0xd5,0xa6,0xa8,0x62,0x84,0xc6,0xc3,0x15,0x34,0x6f, + 0xc8,0xd2,0x34,0x6b,0x3f,0x77,0xdc,0xbd,0x24,0xf1,0x65,0x93,0xd0,0x0e,0x6f,0xf2, + 0xce,0xb3,0x3d,0x76,0xc8,0x20,0xb1,0xdf,0x3c,0x5d,0xad,0x4e,0x5c,0x7f,0xd9,0x6f, + 0x5c,0xb2,0x8a,0xea,0x93,0xde,0xde,0xc2,0xb7,0x58,0x31,0x31,0xed,0x97,0x96,0x48, + 0x87,0xbb,0xe3,0x26,0xd2,0xe5,0x7d,0xe7,0x63,0xd4,0x5b,0x60,0x2a,0x66,0x32,0x60, + 0x33,0x58,0xb5,0xf3,0x92,0x24,0xd6,0x06,0xbc,0xd8,0x9d,0xcb,0x45,0x37,0x93,0x29, + 0x45,0x5b,0x3e,0xe1,0x7b,0x39,0x2f,0x35,0x62,0x76,0x62,0x4c,0xf4,0xc6,0x33,0x60, + 0x81,0x07,0xb5,0x86,0x10,0x28,0x7d,0xfc,0xeb,0x17,0xda,0x7d,0x0f,0xe4,0xc7,0x7b, + 0x3e,0xc5,0x02,0x4b,0xb8,0x18,0x96,0xb9,0x32,0xf7,0xce,0x0d,0x13,0x49,0x30,0xa5, + 0x41,0x1a,0xde,0xea,0x35,0x57,0x26,0x47,0x47,0xff,0x63,0xda,0x92,0x88,0x51,0x00, + 0x43,0x28,0x2b,0x0b,0xa8,0xc7,0xb7,0xba,0xb2,0x3e,0x93,0xaf,0x88,0x61,0x71,0x1d, + 0x29,0xea,0xaf,0x9c,0x34,0x7d,0x27,0x47,0x14,0xfa,0xde,0xdb,0x12,0x78,0x87,0xbb, + 0x0c,0x1f,0xf8,0xca,0x70,0x78,0x54,0xe0,0x68,0x5d,0xf6,0x65,0x86,0x0f,0xdd,0x78, + 0x7b,0x0d,0xf6,0x74,0x98,0x7c,0x32,0x8a,0x1c,0x7d,0x18,0xd3,0x2a,0xdd,0x7f,0xc1, + 0x62,0x1d,0x9f,0xc9,0xf0,0x5a,0x5f,0xeb,0x68,0xee,0x91,0x40,0x07,0x77,0x6f,0x59, + 0x63,0xee,0x3a,0xdc,0xaf,0x0b,0xbb,0x99,0x19,0x3a,0x54,0x8e,0xae,0x2a,0x63,0xe2, + 0xcc,0x52,0x20,0x0a,0x67,0xbb,0x16,0xaf,0xc8,0xcd,0xa0,0x44,0xe7,0x85,0x10,0xed, + 0x2b,0x27,0x2c,0x12,0x0d,0x4f,0xf9,0x34,0x8d,0xf3,0x41,0x11,0xf4,0x9e,0x81,0x10, + 0xde,0xe6,0xdb,0x61,0xd6,0xa9,0xce,0x04,0x65,0x66,0x89,0xcc,0x78,0xef,0x11,0xed, + 0x78,0x22,0xbb,0x26,0xb6,0xc3,0x9d,0x6c,0x66,0xa6,0x15,0xb3,0xc9,0x07,0xbf,0x43, + 0x86,0xc4,0x41,0x41,0xb7,0xe5,0xc4,0x88,0xa7,0xa2,0xa5,0x79,0x60,0x50,0x31,0xbc, + 0xa2,0x7a,0x1d,0xa8,0x13,0xc8,0x58,0x73,0xe0,0xd5,0xf3,0x76,0x3c,0x5d,0xbe,0x43, + 0x5a,0xa5,0xa9,0x43,0x7b,0xe7,0xc5,0x23,0xca,0x09,0x24,0x68,0xa4,0x4d,0x39,0x20, + 0xc7,0x5c,0x79,0x5c,0x13,0xf3,0x96,0x81,0x47,0xf6,0xf9,0x86,0x82,0x54,0x1a,0xf5, + 0xf9,0xeb,0x22,0x02,0x04,0x29,0x8d,0xc8,0xcc,0x2a,0xea,0x3e,0xb7,0xd9,0x54,0x82, + 0xf8,0x2a,0x2b,0xfb,0x2e,0xd6,0xff,0x3d,0xec,0x16,0x61,0x2a,0x26,0xef,0xd8,0x74, + 0xe4,0x18,0xc8,0x6f,0x90,0xea,0x15,0xb3,0x48,0x6e,0x93,0x76,0xa3,0xca,0xee,0xe8, + 0x93,0x20,0x13,0xec,0xad,0xb9,0x8f,0x59,0x32,0x6f,0xe0,0x3f,0x5f,0xa3,0x66,0x48, + 0x0a,0x57,0x46,0x3c,0x90,0xed,0x48,0xed,0xe2,0xd3,0x2d,0x90,0x29,0x1b,0x20,0xc7, + 0xe4,0x9e,0xdb,0xbc,0xc2,0x39,0x53,0x3d,0x61,0x41,0xe2,0x88,0xb6,0x9e,0x63,0x55, + 0xa8,0x73,0x5c,0x54,0x3d,0x2b,0x39,0x7e,0xae,0x5e,0x33,0x77,0x26,0x13,0x32,0xb0, + 0x2a,0x20,0x93,0x6d,0xaf,0x73,0x31,0x66,0x8e,0xce,0xe9,0x18,0x20,0x40,0x7a,0x1b, + 0xd4,0x3b,0x21,0x6e,0x87,0xfd,0x0c,0x5d,0x91,0xb3,0xf5,0xc0,0x9f,0x81,0x1f,0x63, + 0x77,0x5d,0x40,0x94,0x3d,0xdd,0x42,0x2a,0x90,0x72,0x82,0x8b,0x1d,0xf2,0xe6,0x47, + 0xcf,0xe0,0x5a,0x27,0x5d,0xd2,0xce,0xdc,0x8c,0x40,0xf4,0xc1,0x1f,0x63,0x0b,0x0f, + 0x21,0x37,0x4d,0x9e,0x48,0x39,0xf8,0x40,0xfb,0x58,0xc3,0x83,0x1c,0x82,0xf7,0x62, + 0x76,0x34,0x44,0xc8,0xba,0xb9,0x8b,0x32,0x18,0xd7,0xfb,0x06,0x72,0x54,0x6d,0xd0, + 0x2b,0x31,0x7c,0x16,0x73,0x51,0x87,0x80,0xe9,0xb0,0x79,0x7b,0x88,0xb7,0x43,0xfb, + 0x92,0x92,0x9b,0x25,0x1a,0xbb,0x4b,0xea,0xa5,0x24,0xfa,0x77,0x4d,0xb4,0xfa,0xef, + 0x6f,0xe6,0x95,0xde,0x5a,0x85,0x65,0xf2,0xb3,0x2b,0xfa,0x7f,0x77,0xba,0x61,0x8d, + 0x8d,0x67,0x65,0xc9,0x32,0x17,0xb6,0x9b,0x7a,0x77,0xa0,0x96,0x97,0x79,0x91,0xab, + 0x8c,0x66,0x96,0x3e,0xd0,0x39,0x40,0x33,0x25,0xfb,0xee,0xfe,0x3d,0x0c,0xf3,0x18, + 0x0d,0x45,0x33,0x0d,0x26,0xb0,0xf6,0xd9,0x86,0xe8,0x89,0x92,0x73,0x5c,0x94,0x3e, + 0x5a,0x66,0x47,0x87,0x3d,0xfb,0x1f,0x29,0xb5,0x66,0x28,0xbd,0xf9,0x0e,0xf7,0x0c, + 0x2e,0x9a,0x76,0x61,0xc9,0x5c,0x3c,0xa8,0x06,0xd1,0xc8,0xb3,0x9d,0x03,0x16,0x7a, + 0xd0,0x22,0x52,0x57,0x1b,0x89,0x44,0x7d,0xc3,0x82,0x09,0x00,0x9e,0xf2,0x6f,0xa5, + 0xcd,0xbe,0x5b,0x3c,0x1d,0x8e,0x6f,0xc1,0xef,0xc9,0x37,0xf6,0xec,0xf8,0x07,0x19, + 0x2c,0xdb,0x4f,0xd1,0x33,0x32,0x45,0x7c,0x43,0xc0,0x97,0x3d,0x79,0x0a,0x90,0x46, + 0xfc,0xab,0xc4,0x80,0x10,0xe1,0xeb,0x3b,0xbf,0xeb,0x26,0x46,0xa7,0x66,0xf4,0xe0, + 0x09,0x0e,0x48,0x10,0xe2,0x25,0x9c,0xc1,0xfe,0xc1,0x7b,0x73,0x8f,0x69,0x70,0x00, + 0x02,0x0a,0xa1,0x1d,0x6c,0x41,0xec,0x88,0xe2,0x9d,0x99,0x12,0x71,0x0e,0xe1,0x3b, + 0x06,0xf6,0x8f,0x2a,0xbf,0x61,0x47,0xde,0xc7,0xe8,0x1d,0xf2,0x51,0x43,0x40,0x40, + 0x02,0x04,0xc0,0x44,0x12,0x24,0x50,0x60,0x42,0x44,0xd0,0x64,0x52,0x64,0x48,0x50, + 0x03,0x05,0xc8,0x54,0x13,0x25,0x58,0x70,0x43,0x45,0xd8,0x74,0x53,0x65,0x41,0x41, + 0x82,0x06,0xc1,0x45,0x92,0x26,0x51,0x61,0xc2,0x46,0xd1,0x65,0xd2,0x66,0x49,0x51, + 0x83,0x07,0xc9,0x55,0x93,0x27,0x59,0x71,0xc3,0x47,0xd9,0x75,0xd3,0x67,0x62,0x4c, + 0x04,0x83,0x04,0x21,0x2b,0x27,0xef,0xb9,0x23,0x37,0x3e,0xec,0xfb,0x29,0x8a,0x7a, + 0x48,0x49,0xea,0x7c,0x53,0x24,0x44,0xd7,0x1b,0xe2,0x36,0x7e,0xda,0xc4,0x84,0xeb, + 0x0a,0x42,0xd9,0x08,0x3f,0x6b,0x90,0x89,0x7b,0xf5,0x7f,0xad,0x24,0x4a,0x73,0x7b, + 0xca,0xd4,0x27,0x8f,0x98,0x21,0xe6,0x3c,0xa2,0x34,0x8b,0xdd,0x91,0x6b,0x42,0x48, + 0x0a,0x0c,0xc2,0x4c,0x1a,0x2c,0x52,0x68,0x4a,0x4c,0xd2,0x6c,0x5a,0x6c,0x4a,0x58, + 0x0b,0x0d,0xca,0x5c,0x1b,0x2d,0x5a,0x78,0x4b,0x4d,0xda,0x7c,0x5b,0x6d,0x43,0x49, + 0x8a,0x0e,0xc3,0x4d,0x9a,0x2e,0x53,0x69,0xca,0x4e,0xd3,0x6d,0xda,0x6e,0x4b,0x59, + 0x8b,0x0f,0xcb,0x5d,0x9b,0x2f,0x5b,0x79,0xcb,0x4f,0xdb,0x7d,0xdb,0x6f,0xdf,0xf2, + 0x9f,0xaf,0x68,0x04,0xcc,0x10,0xb4,0xb3,0x63,0x34,0xf6,0x24,0x70,0x30,0x6d,0xe2, + 0xde,0xce,0xb4,0x67,0x33,0x95,0x3c,0xb1,0xec,0x17,0x26,0xb6,0xde,0x77,0xfa,0x7f, + 0xa6,0x62,0x29,0x07,0xb1,0x27,0x2d,0x41,0xec,0x3c,0xb5,0x4f,0xf6,0xe2,0xcd,0x89, + 0x59,0x9e,0xe2,0x14,0x79,0xed,0x9e,0x11,0xb5,0x63,0x95,0x6a,0x10,0x7c,0x44,0xc0, + 0x22,0x14,0xc4,0xc4,0x32,0x34,0x54,0xe0,0x62,0x54,0xd4,0xe4,0x72,0x74,0x4c,0xd0, + 0x23,0x15,0xcc,0xd4,0x33,0x35,0x5c,0xf0,0x63,0x55,0xdc,0xf4,0x73,0x75,0x45,0xc1, + 0xa2,0x16,0xc5,0xc5,0xb2,0x36,0x55,0xe1,0xe2,0x56,0xd5,0xe5,0xf2,0x76,0x4d,0xd1, + 0xa3,0x17,0xcd,0xd5,0xb3,0x37,0x5d,0xf1,0xe3,0x57,0xdd,0xf5,0xf3,0x77,0xf9,0x76, + 0x2e,0xa8,0x46,0x9f,0xe7,0x5a,0x30,0x69,0xec,0xfc,0x06,0xad,0x58,0x78,0xce,0x98, + 0x6d,0x58,0x3d,0x18,0xc1,0x1b,0x66,0x3c,0x31,0x25,0x9e,0xbc,0x79,0x79,0x32,0xfb, + 0x57,0xc5,0x67,0xb2,0x44,0x58,0x5f,0xae,0x8b,0x7a,0x97,0xad,0xf8,0x7a,0xe3,0x19, + 0x55,0x3b,0xbc,0x1d,0x9d,0x55,0xaf,0xa5,0x08,0x38,0x9f,0xbd,0xf9,0x7b,0x46,0xc8, + 0x2a,0x1c,0xc6,0xcc,0x3a,0x3c,0x56,0xe8,0x6a,0x5c,0xd6,0xec,0x7a,0x7c,0x4e,0xd8, + 0x2b,0x1d,0xce,0xdc,0x3b,0x3d,0x5e,0xf8,0x6b,0x5d,0xde,0xfc,0x7b,0x7d,0x47,0xc9, + 0xaa,0x1e,0xc7,0xcd,0xba,0x3e,0x57,0xe9,0xea,0x5e,0xd7,0xed,0xfa,0x7e,0x4f,0xd9, + 0xab,0x1f,0xcf,0xdd,0xbb,0x3f,0x5f,0xf9,0xeb,0x5f,0xdf,0xfd,0xfb,0x7f,0x58,0x80, + 0x01,0x60,0x5e,0x84,0xea,0x1f,0x60,0x82,0xf7,0x7f,0xee,0x31,0x5c,0xe0,0xa0,0x06, + 0xa4,0x09,0xd6,0x10,0xf4,0x22,0x50,0xf0,0xc3,0x34,0x28,0xf1,0x57,0x14,0x7b,0x1e, + 0x27,0x84,0x99,0xf9,0xf4,0xae,0x82,0xdd,0x38,0x3d,0xd9,0xe5,0x52,0x17,0xa9,0xf1, + 0x24,0x09,0xde,0xe4,0x19,0x5e,0xa9,0xf4,0xc7,0x36,0xbd,0x70,0x54,0xed,0x60,0x42, + 0x06,0x84,0xe0,0x46,0x16,0xa4,0x70,0x62,0x46,0xc4,0xf0,0x66,0x56,0xe4,0x68,0x52, + 0x07,0x85,0xe8,0x56,0x17,0xa5,0x78,0x72,0x47,0xc5,0xf8,0x76,0x57,0xe5,0x61,0x43, + 0x86,0x86,0xe1,0x47,0x96,0xa6,0x71,0x63,0xc6,0xc6,0xf1,0x67,0xd6,0xe6,0x69,0x53, + 0x87,0x87,0xe9,0x57,0x97,0xa7,0x79,0x73,0xc7,0xc7,0xf9,0x77,0xd7,0xe7,0xd9,0xe8, + 0x0a,0x38,0xda,0x70,0x5c,0x22,0x36,0x6d,0xcd,0xc6,0x0d,0x8e,0xfd,0x48,0xba,0x9e, + 0x55,0x81,0xd2,0x9c,0x3c,0xdb,0xfa,0x23,0x12,0x34,0x39,0xfc,0xde,0xaf,0xd0,0x6b, + 0xec,0x81,0x74,0x8d,0x62,0x15,0x90,0xeb,0x10,0xe0,0x34,0x90,0xdc,0xca,0xf4,0x17, + 0x8b,0x3b,0xf1,0x1e,0x3e,0xea,0x23,0xd5,0x05,0xe1,0x0c,0x1b,0xdb,0x5b,0x62,0x4a, + 0x0e,0x8c,0xe2,0x4e,0x1e,0xac,0x72,0x6a,0x4e,0xcc,0xf2,0x6e,0x5e,0xec,0x6a,0x5a, + 0x0f,0x8d,0xea,0x5e,0x1f,0xad,0x7a,0x7a,0x4f,0xcd,0xfa,0x7e,0x5f,0xed,0x63,0x4b, + 0x8e,0x8e,0xe3,0x4f,0x9e,0xae,0x73,0x6b,0xce,0xce,0xf3,0x6f,0xde,0xee,0x6b,0x5b, + 0x8f,0x8f,0xeb,0x5f,0x9f,0xaf,0x7b,0x7b,0xcf,0xcf,0xfb,0x7f,0xdf,0xef,0x88,0xc0, + 0xa7,0x44,0xe4,0xb9,0x3c,0xdc,0xcb,0x60,0xe7,0x96,0xb4,0xa6,0x74,0xf0,0xd1,0x3b, + 0x07,0x4e,0x43,0x66,0x6d,0xbe,0x2e,0x12,0x3d,0x83,0xbc,0xb6,0x75,0xf1,0xde,0x9c, + 0x5b,0x39,0x8d,0x45,0x36,0xba,0x82,0x87,0xc6,0xe2,0xb5,0xa7,0xf4,0xf2,0xa9,0x62, + 0x1a,0x13,0xcd,0xd7,0x4e,0xbe,0x0a,0x1b,0x19,0xb0,0xbd,0xb7,0xf5,0xf3,0x64,0xc2, + 0x26,0x94,0xe4,0xc6,0x36,0xb4,0x74,0xe2,0x66,0xd4,0xf4,0xe6,0x76,0xf4,0x6c,0xd2, + 0x27,0x95,0xec,0xd6,0x37,0xb5,0x7c,0xf2,0x67,0xd5,0xfc,0xf6,0x77,0xf5,0x65,0xc3, + 0xa6,0x96,0xe5,0xc7,0xb6,0xb6,0x75,0xe3,0xe6,0xd6,0xf5,0xe7,0xf6,0xf6,0x6d,0xd3, + 0xa7,0x97,0xed,0xd7,0xb7,0xb7,0x7d,0xf3,0xe7,0xd7,0xfd,0xf7,0xf7,0xf7,0x78,0x65, + 0x2a,0x33,0xd4,0x97,0x7c,0x43,0xf6,0xbb,0x12,0x75,0xb6,0xae,0x7c,0xf8,0x2d,0x3a, + 0x9e,0x26,0xae,0x5c,0xbe,0xff,0x66,0x32,0x84,0xca,0xbe,0xbe,0x7d,0xf9,0xda,0x1a, + 0xc7,0xe5,0xa3,0x8d,0xb8,0x41,0x26,0x3b,0x85,0xb9,0xb7,0xaf,0xfc,0xfa,0x71,0x74, + 0xbb,0x0f,0x18,0xbb,0x3f,0xb3,0x93,0x29,0xe9,0xd3,0xbf,0xbf,0xfd,0xfb,0x66,0xca, + 0x2e,0x9c,0xe6,0xce,0x3e,0xbc,0x76,0xea,0x6e,0xdc,0xf6,0xee,0x7e,0xfc,0x6e,0xda, + 0x2f,0x9d,0xee,0xde,0x3f,0xbd,0x7e,0xfa,0x6f,0xdd,0xfe,0xfe,0x7f,0xfd,0x67,0xcb, + 0xae,0x9e,0xe7,0xcf,0xbe,0xbe,0x77,0xeb,0xee,0xde,0xf7,0xef,0xfe,0xfe,0x6f,0xdb, + 0xaf,0x9f,0xef,0xdf,0xbf,0xbf,0x7f,0xfb,0xef,0xdf,0xff,0xff,0x88,0x9f,*/ +}; +#endif + +#endif \ No newline at end of file diff --git a/drivers/amlogic/input/touchscreen/gt9xx/gt9xx_update.c b/drivers/amlogic/input/touchscreen/gt9xx/gt9xx_update.c new file mode 100644 index 0000000000000..fdcdcc7539b4f --- /dev/null +++ b/drivers/amlogic/input/touchscreen/gt9xx/gt9xx_update.c @@ -0,0 +1,3626 @@ +/* + * Goodix GT9xx touchscreen driver + * + * Copyright (C) 2010 - 2016 Goodix. Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be a reference + * to you, when you are integrating the GOODiX's CTP IC into your system, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * Version: 2.4.0.1 + * Release Date: 2016/10/26 + */ + +#include +#include "gt9xx.h" + +#include +#include +#if ((GTP_AUTO_UPDATE && GTP_HEADER_FW_UPDATE) || GTP_COMPATIBLE_MODE) + #include "gt9xx_firmware.h" +#endif + +#define GUP_REG_HW_INFO 0x4220 +#define GUP_REG_FW_MSG 0x41E4 +#define GUP_REG_PID_VID 0x8140 + +#define GUP_SEARCH_FILE_TIMES 50 + +#define UPDATE_FILE_PATH_1 "/data/_goodix_update_.bin" +#define UPDATE_FILE_PATH_2 "/sdcard/_goodix_update_.bin" + +#define CONFIG_FILE_PATH_1 "/data/_goodix_config_.cfg" +#define CONFIG_FILE_PATH_2 "/sdcard/_goodix_config_.cfg" + +#define FW_HEAD_LENGTH 14 +#define FW_SECTION_LENGTH 0x2000 // 8K +#define FW_DSP_ISP_LENGTH 0x1000 // 4K +#define FW_DSP_LENGTH 0x1000 // 4K +#define FW_BOOT_LENGTH 0x800 // 2K +#define FW_SS51_LENGTH (4 * FW_SECTION_LENGTH) // 32K +#define FW_BOOT_ISP_LENGTH 0x800 // 2k +#define FW_GLINK_LENGTH 0x3000 // 12k +#define FW_GWAKE_LENGTH (4 * FW_SECTION_LENGTH) // 32k + +#define PACK_SIZE 256 +#define MAX_FRAME_CHECK_TIME 5 + + +#define _bRW_MISCTL__SRAM_BANK 0x4048 +#define _bRW_MISCTL__MEM_CD_EN 0x4049 +#define _bRW_MISCTL__CACHE_EN 0x404B +#define _bRW_MISCTL__TMR0_EN 0x40B0 +#define _rRW_MISCTL__SWRST_B0_ 0x4180 +#define _bWO_MISCTL__CPU_SWRST_PULSE 0x4184 +#define _rRW_MISCTL__BOOTCTL_B0_ 0x4190 +#define _rRW_MISCTL__BOOT_OPT_B0_ 0x4218 +#define _rRW_MISCTL__BOOT_CTL_ 0x5094 + +#define AUTO_SEARCH_BIN 0x01 +#define AUTO_SEARCH_CFG 0x02 +#define BIN_FILE_READY 0x80 +#define CFG_FILE_READY 0x08 +#define HEADER_FW_READY 0x00 + +#pragma pack(1) +typedef struct +{ + u8 hw_info[4]; //hardware info// + u8 pid[8]; //product id // + u16 vid; //version id // +}st_fw_head; +#pragma pack() + +typedef struct +{ + u8 force_update; + u8 fw_flag; + struct file *file; + struct file *cfg_file; + st_fw_head ic_fw_msg; + mm_segment_t old_fs; + u32 fw_total_len; + u32 fw_burned_len; +}st_update_msg; + +st_update_msg update_msg; +u16 show_len; +u16 total_len; +u8 got_file_flag = 0; +u8 searching_file = 0; + +extern u8 config[GTP_CONFIG_MAX_LENGTH + GTP_ADDR_LENGTH]; +extern void gtp_reset_guitar(struct i2c_client *client, s32 ms); +extern s32 gtp_send_cfg(struct i2c_client *client); +extern s32 gtp_read_version(struct i2c_client *, u16* ); +extern struct i2c_client * i2c_connect_client; +extern void gtp_irq_enable(struct goodix_ts_data *ts); +extern void gtp_irq_disable(struct goodix_ts_data *ts); +extern s32 gtp_i2c_read_dbl_check(struct i2c_client *, u16, u8 *, int); +static u8 gup_burn_fw_gwake_section(struct i2c_client *client, u8 *fw_section, u16 start_addr, u32 len, u8 bank_cmd ); + +#define _CLOSE_FILE(p_file) if (p_file && !IS_ERR(p_file)) \ + { \ + filp_close(p_file, NULL); \ + } + +#if GTP_ESD_PROTECT +extern void gtp_esd_switch(struct i2c_client *, s32); +#endif + +#if GTP_COMPATIBLE_MODE +s32 gup_fw_download_proc(void *dir, u8 dwn_mode); +#endif +/******************************************************* +Function: + Read data from the i2c slave device. +Input: + client: i2c device. + buf[0~1]: read start address. + buf[2~len-1]: read data buffer. + len: GTP_ADDR_LENGTH + read bytes count +Output: + numbers of i2c_msgs to transfer: + 2: succeed, otherwise: failed +*********************************************************/ +s32 gup_i2c_read(struct i2c_client *client, u8 *buf, s32 len) +{ + struct i2c_msg msgs[2]; + s32 ret=-1; + s32 retries = 0; + + GTP_DEBUG_FUNC(); + + msgs[0].flags = !I2C_M_RD; + msgs[0].addr = client->addr; + msgs[0].len = GTP_ADDR_LENGTH; + msgs[0].buf = &buf[0]; + //msgs[0].scl_rate = 300 * 1000; // for Rockchip, etc + + msgs[1].flags = I2C_M_RD; + msgs[1].addr = client->addr; + msgs[1].len = len - GTP_ADDR_LENGTH; + msgs[1].buf = &buf[GTP_ADDR_LENGTH]; + //msgs[1].scl_rate = 300 * 1000; // for Rockchip, etc. + + while(retries < 5) + { + ret = i2c_transfer(client->adapter, msgs, 2); + if(ret == 2)break; + retries++; + } + + return ret; +} + +/******************************************************* +Function: + Write data to the i2c slave device. +Input: + client: i2c device. + buf[0~1]: write start address. + buf[2~len-1]: data buffer + len: GTP_ADDR_LENGTH + write bytes count +Output: + numbers of i2c_msgs to transfer: + 1: succeed, otherwise: failed +*********************************************************/ +s32 gup_i2c_write(struct i2c_client *client,u8 *buf,s32 len) +{ + struct i2c_msg msg; + s32 ret=-1; + s32 retries = 0; + + GTP_DEBUG_FUNC(); + + msg.flags = !I2C_M_RD; + msg.addr = client->addr; + msg.len = len; + msg.buf = buf; + //msg.scl_rate = 300 * 1000; // for Rockchip, etc + + while(retries < 5) + { + ret = i2c_transfer(client->adapter, &msg, 1); + if (ret == 1)break; + retries++; + } + + return ret; +} + +static s32 gup_init_panel(struct goodix_ts_data *ts) +{ + s32 ret = 0; + s32 i = 0; + u8 check_sum = 0; + u8 opr_buf[16]; + u8 sensor_id = 0; + u16 version = 0; + u8 drv_cfg_version; + u8 flash_cfg_version; + +#ifndef GTP_CONFIG_OF + u8 cfg_info_group0[] = CTP_CFG_GROUP0; + u8 cfg_info_group1[] = CTP_CFG_GROUP1; + u8 cfg_info_group2[] = CTP_CFG_GROUP2; + u8 cfg_info_group3[] = CTP_CFG_GROUP3; + u8 cfg_info_group4[] = CTP_CFG_GROUP4; + u8 cfg_info_group5[] = CTP_CFG_GROUP5; + u8 *send_cfg_buf[] = {cfg_info_group0,cfg_info_group1, + cfg_info_group2, cfg_info_group3, + cfg_info_group4, cfg_info_group5}; + u8 cfg_info_len[] = { CFG_GROUP_LEN(cfg_info_group0), + CFG_GROUP_LEN(cfg_info_group1), + CFG_GROUP_LEN(cfg_info_group2), + CFG_GROUP_LEN(cfg_info_group3), + CFG_GROUP_LEN(cfg_info_group4), + CFG_GROUP_LEN(cfg_info_group5)}; + #endif + + ret = gtp_i2c_read_dbl_check(ts->client, GTP_REG_SENSOR_ID, &sensor_id, 1); + if (SUCCESS == ret) + { + if (sensor_id >= 0x06) + { + GTP_ERROR("Invalid sensor_id(0x%02X), No Config Sent!", sensor_id); + return -1; + } + } + else + { + GTP_ERROR("Failed to get sensor_id, No config sent!"); + return -1; + } + + /* parse config data*/ +#ifdef GTP_CONFIG_OF + GTP_DEBUG("Get config data from dts file."); + ret = gtp_parse_dt_cfg(&ts->client->dev, &config[GTP_ADDR_LENGTH], &ts->gtp_cfg_len, sensor_id); + if (ret < 0) { + GTP_ERROR("Failed to parse config data form dts file."); + ts->pnl_init_error = 1; + return -1; + } +#else + GTP_DEBUG("Get config data from header file."); + if ((!cfg_info_len[1]) && (!cfg_info_len[2]) && + (!cfg_info_len[3]) && (!cfg_info_len[4]) && + (!cfg_info_len[5])) + { + sensor_id = 0; + } + ts->gtp_cfg_len = cfg_info_len[sensor_id]; + memset(&config[GTP_ADDR_LENGTH], 0, GTP_CONFIG_MAX_LENGTH); + memcpy(&config[GTP_ADDR_LENGTH], send_cfg_buf[sensor_id], ts->gtp_cfg_len); +#endif + + GTP_DEBUG("Sensor_ID: %d", sensor_id); + + if (ts->gtp_cfg_len < GTP_CONFIG_MIN_LENGTH) + { + GTP_ERROR("Sensor_ID(%d) matches with NULL or INVALID CONFIG GROUP! NO Config Sent! You need to check you header file CFG_GROUP section!", sensor_id); + return -1; + } + + ret = gtp_i2c_read_dbl_check(ts->client, GTP_REG_CONFIG_DATA, &opr_buf[0], 1); + if (ret == SUCCESS) + { + GTP_DEBUG("CFG_GROUP%d Config Version: %d, IC Config Version: %d", sensor_id, + config[GTP_ADDR_LENGTH], opr_buf[0]); + + flash_cfg_version = opr_buf[0]; + drv_cfg_version = config[GTP_ADDR_LENGTH]; + + if (flash_cfg_version < 90 && flash_cfg_version > drv_cfg_version) { + config[GTP_ADDR_LENGTH] = 0x00; + } + } + else + { + GTP_ERROR("Failed to get ic config version!No config sent!"); + return -1; + } + + GTP_DEBUG("X_MAX = %d, Y_MAX = %d, TRIGGER = 0x%02x", + ts->abs_x_max, ts->abs_y_max, ts->int_trigger_type); + + config[RESOLUTION_LOC] = (u8)GTP_MAX_WIDTH; + config[RESOLUTION_LOC + 1] = (u8)(GTP_MAX_WIDTH>>8); + config[RESOLUTION_LOC + 2] = (u8)GTP_MAX_HEIGHT; + config[RESOLUTION_LOC + 3] = (u8)(GTP_MAX_HEIGHT>>8); + + if (GTP_INT_TRIGGER == 0) //RISING + { + config[TRIGGER_LOC] &= 0xfe; + } + else if (GTP_INT_TRIGGER == 1) //FALLING + { + config[TRIGGER_LOC] |= 0x01; + } + + check_sum = 0; + for (i = GTP_ADDR_LENGTH; i < ts->gtp_cfg_len; i++) + { + check_sum += config[i]; + } + config[ts->gtp_cfg_len] = (~check_sum) + 1; + + GTP_DEBUG_FUNC(); + ret = gtp_send_cfg(ts->client); + if (ret < 0) + { + GTP_ERROR("Send config error."); + } + + if (flash_cfg_version < 90 && flash_cfg_version > drv_cfg_version) { + check_sum = 0; + config[GTP_ADDR_LENGTH] = drv_cfg_version; + for (i = GTP_ADDR_LENGTH; i < ts->gtp_cfg_len; i++) { + check_sum += config[i]; + } + config[ts->gtp_cfg_len] = (~check_sum) + 1; + } + gtp_read_version(ts->client, &version); + msleep(10); + return 0; +} + + +static u8 gup_get_ic_msg(struct i2c_client *client, u16 addr, u8* msg, s32 len) +{ + s32 i = 0; + + msg[0] = (addr >> 8) & 0xff; + msg[1] = addr & 0xff; + + for (i = 0; i < 5; i++) + { + if (gup_i2c_read(client, msg, GTP_ADDR_LENGTH + len) > 0) + { + break; + } + } + + if (i >= 5) + { + GTP_ERROR("Read data from 0x%02x%02x failed!", msg[0], msg[1]); + return FAIL; + } + + return SUCCESS; +} + +static u8 gup_set_ic_msg(struct i2c_client *client, u16 addr, u8 val) +{ + s32 i = 0; + u8 msg[3]; + + msg[0] = (addr >> 8) & 0xff; + msg[1] = addr & 0xff; + msg[2] = val; + + for (i = 0; i < 5; i++) + { + if (gup_i2c_write(client, msg, GTP_ADDR_LENGTH + 1) > 0) + { + break; + } + } + + if (i >= 5) + { + GTP_ERROR("Set data to 0x%02x%02x failed!", msg[0], msg[1]); + return FAIL; + } + + return SUCCESS; +} + +static u8 gup_get_ic_fw_msg(struct i2c_client *client) +{ + s32 ret = -1; + u8 retry = 0; + u8 buf[16]; + u8 i; + + // step1:get hardware info + ret = gtp_i2c_read_dbl_check(client, GUP_REG_HW_INFO, &buf[GTP_ADDR_LENGTH], 4); + if (FAIL == ret) + { + GTP_ERROR("[get_ic_fw_msg]get hw_info failed,exit"); + return FAIL; + } + + // buf[2~5]: 00 06 90 00 + // hw_info: 00 90 06 00 + for(i=0; i<4; i++) + { + update_msg.ic_fw_msg.hw_info[i] = buf[GTP_ADDR_LENGTH + 3 - i]; + } + GTP_DEBUG("IC Hardware info:%02x%02x%02x%02x", update_msg.ic_fw_msg.hw_info[0], update_msg.ic_fw_msg.hw_info[1], + update_msg.ic_fw_msg.hw_info[2], update_msg.ic_fw_msg.hw_info[3]); + // step2:get firmware message + for(retry=0; retry<2; retry++) + { + ret = gup_get_ic_msg(client, GUP_REG_FW_MSG, buf, 1); + if(FAIL == ret) + { + GTP_ERROR("Read firmware message fail."); + return ret; + } + + update_msg.force_update = buf[GTP_ADDR_LENGTH]; + if((0xBE != update_msg.force_update)&&(!retry)) + { + GTP_INFO("The check sum in ic is error."); + GTP_INFO("The IC will be updated by force."); + continue; + } + break; + } + GTP_DEBUG("IC force update flag:0x%x", update_msg.force_update); + + // step3:get pid & vid + ret = gtp_i2c_read_dbl_check(client, GUP_REG_PID_VID, &buf[GTP_ADDR_LENGTH], 6); + if (FAIL == ret) + { + GTP_ERROR("[get_ic_fw_msg]get pid & vid failed,exit"); + return FAIL; + } + + memset(update_msg.ic_fw_msg.pid, 0, sizeof(update_msg.ic_fw_msg.pid)); + memcpy(update_msg.ic_fw_msg.pid, &buf[GTP_ADDR_LENGTH], 4); + GTP_DEBUG("IC Product id:%s", update_msg.ic_fw_msg.pid); + + //GT9XX PID MAPPING + /*|-----FLASH-----RAM-----| + |------918------918-----| + |------968------968-----| + |------913------913-----| + |------913P-----913P----| + |------927------927-----| + |------927P-----927P----| + |------9110-----9110----| + |------9110P----9111----|*/ + if(update_msg.ic_fw_msg.pid[0] != 0) + { + if(!memcmp(update_msg.ic_fw_msg.pid, "9111", 4)) + { + GTP_DEBUG("IC Mapping Product id:%s", update_msg.ic_fw_msg.pid); + memcpy(update_msg.ic_fw_msg.pid, "9110P", 5); + } + } + + update_msg.ic_fw_msg.vid = buf[GTP_ADDR_LENGTH+4] + (buf[GTP_ADDR_LENGTH+5]<<8); + GTP_DEBUG("IC version id:%04x", update_msg.ic_fw_msg.vid); + + return SUCCESS; +} + +s32 gup_enter_update_mode(struct i2c_client *client) +{ + s32 ret = -1; + s32 retry = 0; + u8 rd_buf[3]; + + //step1:RST output low last at least 2ms + GTP_GPIO_OUTPUT(gtp_rst_gpio, 0); + msleep(2); + + //step2:select I2C slave addr,INT:0--0xBA;1--0x28. + GTP_GPIO_OUTPUT(gtp_int_gpio, (client->addr == 0x14)); + msleep(2); + + //step3:RST output high reset guitar + GTP_GPIO_OUTPUT(gtp_rst_gpio, 1); + + //20121211 modify start + msleep(5); + while(retry++ < 200) + { + //step4:Hold ss51 & dsp + ret = gup_set_ic_msg(client, _rRW_MISCTL__SWRST_B0_, 0x0C); + if(ret <= 0) + { + GTP_DEBUG("Hold ss51 & dsp I2C error,retry:%d", retry); + continue; + } + + //step5:Confirm hold + ret = gup_get_ic_msg(client, _rRW_MISCTL__SWRST_B0_, rd_buf, 1); + if(ret <= 0) + { + GTP_DEBUG("Hold ss51 & dsp I2C error,retry:%d", retry); + continue; + } + if(0x0C == rd_buf[GTP_ADDR_LENGTH]) + { + GTP_DEBUG("Hold ss51 & dsp confirm SUCCESS"); + break; + } + GTP_DEBUG("Hold ss51 & dsp confirm 0x4180 failed,value:%d", rd_buf[GTP_ADDR_LENGTH]); + } + if(retry >= 200) + { + GTP_ERROR("Enter update Hold ss51 failed."); + return FAIL; + } + + //step6:DSP_CK and DSP_ALU_CK PowerOn + ret = gup_set_ic_msg(client, 0x4010, 0x00); + + //20121211 modify end + return ret; +} + +void gup_leave_update_mode(void) +{ + GTP_GPIO_AS_INT(gtp_int_gpio); + + GTP_DEBUG("[leave_update_mode]reset chip."); + gtp_reset_guitar(i2c_connect_client, 20); +} + +// Get the correct nvram data +// The correct conditions: +// 1. the hardware info is the same +// 2. the product id is the same +// 3. the firmware version in update file is greater than the firmware version in ic +// or the check sum in ic is wrong +/* Update Conditions: + 1. Same hardware info + 2. Same PID + 3. File VID > IC VID + Force Update Conditions: + 1. Wrong ic firmware checksum + 2. INVALID IC PID or VID + 3. (IC PID == 91XX || File PID == 91XX) && (File VID > IC VID) +*/ + +static u8 gup_enter_update_judge(st_fw_head *fw_head) +{ + u16 u16_tmp; + s32 i = 0; + u32 fw_len = 0; + s32 pid_cmp_len = 0; + u16_tmp = fw_head->vid; + fw_head->vid = (u16)(u16_tmp>>8) + (u16)(u16_tmp<<8); + + GTP_INFO("FILE HARDWARE INFO:%02x%02x%02x%02x", fw_head->hw_info[0], fw_head->hw_info[1], fw_head->hw_info[2], fw_head->hw_info[3]); + GTP_INFO("FILE PID:%s", fw_head->pid); + GTP_INFO("FILE VID:%04x", fw_head->vid); + GTP_INFO("IC HARDWARE INFO:%02x%02x%02x%02x", update_msg.ic_fw_msg.hw_info[0], update_msg.ic_fw_msg.hw_info[1], + update_msg.ic_fw_msg.hw_info[2], update_msg.ic_fw_msg.hw_info[3]); + GTP_INFO("IC PID:%s", update_msg.ic_fw_msg.pid); + GTP_INFO("IC VID:%04x", update_msg.ic_fw_msg.vid); + + if (!memcmp(fw_head->pid, "9158", 4) && !memcmp(update_msg.ic_fw_msg.pid, "915S", 4)) + { + GTP_INFO("Update GT915S to GT9158 directly!"); + return SUCCESS; + } + //First two conditions + if (!memcmp(fw_head->hw_info, update_msg.ic_fw_msg.hw_info, sizeof(update_msg.ic_fw_msg.hw_info))) + { + fw_len = 42 * 1024; + } + else + { + fw_len = fw_head->hw_info[3]; + fw_len += (((u32)fw_head->hw_info[2]) << 8); + fw_len += (((u32)fw_head->hw_info[1]) << 16); + fw_len += (((u32)fw_head->hw_info[0]) << 24); + } + if (update_msg.fw_total_len != fw_len) + { + GTP_ERROR("Inconsistent firmware size, Update aborted! Default size: %d(%dK), actual size: %d(%dK)", fw_len, fw_len/1024, update_msg.fw_total_len, update_msg.fw_total_len/1024); + return FAIL; + } + GTP_INFO("Firmware length:%d(%dK)", update_msg.fw_total_len, update_msg.fw_total_len/1024); + + if (update_msg.force_update != 0xBE) + { + GTP_INFO("FW chksum error,need enter update."); + return SUCCESS; + } + + // 20130523 start + if (strlen(update_msg.ic_fw_msg.pid) < 3) + { + GTP_INFO("Illegal IC pid, need enter update"); + return SUCCESS; + } + else + { + for (i = 0; i < 3; i++) + { + if ((update_msg.ic_fw_msg.pid[i] < 0x30) || (update_msg.ic_fw_msg.pid[i] > 0x39)) + { + GTP_INFO("Illegal IC pid, out of bound, need enter update"); + return SUCCESS; + } + } + } + // 20130523 end + + pid_cmp_len = strlen(fw_head->pid); + if (pid_cmp_len < strlen(update_msg.ic_fw_msg.pid)) + { + pid_cmp_len = strlen(update_msg.ic_fw_msg.pid); + } + + if ((!memcmp(fw_head->pid, update_msg.ic_fw_msg.pid, pid_cmp_len)) || + (!memcmp(update_msg.ic_fw_msg.pid, "91XX", 4))|| + (!memcmp(fw_head->pid, "91XX", 4))) + { + if(!memcmp(fw_head->pid, "91XX", 4)) + { + GTP_DEBUG("Force none same pid update mode."); + } + else + { + GTP_DEBUG("Get the same pid."); + } + + //The third condition + if (fw_head->vid > update_msg.ic_fw_msg.vid) + { + GTP_INFO("Need enter update."); + return SUCCESS; + } + GTP_ERROR("Don't meet the third condition."); + GTP_ERROR("File VID <= Ic VID, update aborted!"); + } + else + { + GTP_ERROR("File PID != Ic PID, update aborted!"); + } + + return FAIL; +} + + + +#if GTP_AUTO_UPDATE_CFG +static u8 ascii2hex(u8 a) +{ + s8 value = 0; + + if(a >= '0' && a <= '9') + { + value = a - '0'; + } + else if(a >= 'A' && a <= 'F') + { + value = a - 'A' + 0x0A; + } + else if(a >= 'a' && a <= 'f') + { + value = a - 'a' + 0x0A; + } + else + { + value = 0xff; + } + + return value; +} + +static s8 gup_update_config(struct i2c_client *client) +{ + s32 file_len = 0; + s32 ret = 0; + s32 i = 0; + s32 file_cfg_len = 0; + s32 chip_cfg_len = 0; + s32 count = 0; + u8 *buf; + u8 *pre_buf; + u8 *file_config; + //u8 checksum = 0; + struct goodix_ts_data *ts = i2c_get_clientdata(client); + + if(NULL == update_msg.cfg_file) + { + GTP_ERROR("[update_cfg]No need to upgrade config!"); + return FAIL; + } + file_len = update_msg.cfg_file->f_op->llseek(update_msg.cfg_file, 0, SEEK_END); + + chip_cfg_len = ts->gtp_cfg_len; + + GTP_DEBUG("[update_cfg]config file len:%d", file_len); + GTP_DEBUG("[update_cfg]need config len:%d", chip_cfg_len); + if((file_len+5) < chip_cfg_len*5) + { + GTP_ERROR("Config length error"); + return -1; + } + + buf = (u8*)kzalloc(file_len, GFP_KERNEL); + pre_buf = (u8*)kzalloc(file_len, GFP_KERNEL); + file_config = (u8*)kzalloc(chip_cfg_len + GTP_ADDR_LENGTH, GFP_KERNEL); + update_msg.cfg_file->f_op->llseek(update_msg.cfg_file, 0, SEEK_SET); + + GTP_DEBUG("[update_cfg]Read config from file."); + ret = update_msg.cfg_file->f_op->read(update_msg.cfg_file, (char*)pre_buf, file_len, &update_msg.cfg_file->f_pos); + if(ret<0) + { + GTP_ERROR("[update_cfg]Read config file failed."); + goto update_cfg_file_failed; + } + + GTP_DEBUG("[update_cfg]Delete illgal charactor."); + for(i=0,count=0; i> 8; + file_config[1] = GTP_REG_CONFIG_DATA & 0xff; + for(i=0,file_cfg_len=GTP_ADDR_LENGTH; i 0) + { + GTP_INFO("[update_cfg]Send config SUCCESS."); + break; + } + GTP_ERROR("[update_cfg]Send config i2c error."); + } + +update_cfg_file_failed: + kfree(pre_buf); + kfree(buf); + kfree(file_config); + return ret; +} + +#endif + +#if (GTP_AUTO_UPDATE && (!GTP_HEADER_FW_UPDATE || GTP_AUTO_UPDATE_CFG)) +static void gup_search_file(s32 search_type) +{ + s32 i = 0; + struct file *pfile = NULL; + + got_file_flag = 0x00; + + searching_file = 1; + for (i = 0; i < GUP_SEARCH_FILE_TIMES; ++i) + { + if (0 == searching_file) + { + GTP_INFO("Force exiting file searching"); + got_file_flag = 0x00; + return; + } + + if (search_type & AUTO_SEARCH_BIN) + { + GTP_DEBUG("Search for %s, %s for fw update.(%d/%d)", UPDATE_FILE_PATH_1, UPDATE_FILE_PATH_2, i+1, GUP_SEARCH_FILE_TIMES); + pfile = filp_open(UPDATE_FILE_PATH_1, O_RDONLY, 0); + if (IS_ERR(pfile)) + { + pfile = filp_open(UPDATE_FILE_PATH_2, O_RDONLY, 0); + if (!IS_ERR(pfile)) + { + GTP_INFO("Bin file: %s for fw update.", UPDATE_FILE_PATH_2); + got_file_flag |= BIN_FILE_READY; + update_msg.file = pfile; + } + } + else + { + GTP_INFO("Bin file: %s for fw update.", UPDATE_FILE_PATH_1); + got_file_flag |= BIN_FILE_READY; + update_msg.file = pfile; + } + if (got_file_flag & BIN_FILE_READY) + { + #if GTP_AUTO_UPDATE_CFG + if (search_type & AUTO_SEARCH_CFG) + { + i = GUP_SEARCH_FILE_TIMES; // Bin & Cfg File required to be in the same directory + } + else + #endif + { + searching_file = 0; + return; + } + } + } + + #if GTP_AUTO_UPDATE_CFG + if ( (search_type & AUTO_SEARCH_CFG) && !(got_file_flag & CFG_FILE_READY) ) + { + GTP_DEBUG("Search for %s, %s for config update.(%d/%d)", CONFIG_FILE_PATH_1, CONFIG_FILE_PATH_2, i+1, GUP_SEARCH_FILE_TIMES); + pfile = filp_open(CONFIG_FILE_PATH_1, O_RDONLY, 0); + if (IS_ERR(pfile)) + { + pfile = filp_open(CONFIG_FILE_PATH_2, O_RDONLY, 0); + if (!IS_ERR(pfile)) + { + GTP_INFO("Cfg file: %s for config update.", CONFIG_FILE_PATH_2); + got_file_flag |= CFG_FILE_READY; + update_msg.cfg_file = pfile; + } + } + else + { + GTP_INFO("Cfg file: %s for config update.", CONFIG_FILE_PATH_1); + got_file_flag |= CFG_FILE_READY; + update_msg.cfg_file = pfile; + } + if (got_file_flag & CFG_FILE_READY) + { + searching_file = 0; + return; + } + } + #endif + msleep(3000); + } + searching_file = 0; +} +#endif + + +static u8 gup_check_update_file(struct i2c_client *client, st_fw_head* fw_head, u8* path) +{ + s32 ret = 0; + s32 i = 0; + s32 fw_checksum = 0; + u8 buf[FW_HEAD_LENGTH]; + + got_file_flag = 0x00; + if (path) + { + GTP_DEBUG("Update File path:%s, %d", path, (int)strlen(path)); + update_msg.file = filp_open(path, O_RDONLY, 0); + + if (IS_ERR(update_msg.file)) + { + GTP_ERROR("Open update file(%s) error!", path); + return FAIL; + } + got_file_flag = BIN_FILE_READY; + } + else + { +#if GTP_AUTO_UPDATE + #if GTP_HEADER_FW_UPDATE + GTP_INFO("Update by default firmware array"); + update_msg.fw_total_len = sizeof(gtp_default_FW) - FW_HEAD_LENGTH; + if (sizeof(gtp_default_FW) < (FW_HEAD_LENGTH+FW_SECTION_LENGTH*4+FW_DSP_ISP_LENGTH+FW_DSP_LENGTH+FW_BOOT_LENGTH)) + { + GTP_ERROR("INVALID gtp_default_FW, check your gt9xx_firmware.h file!"); + return FAIL; + } + GTP_DEBUG("Firmware actual size: %d(%dK)", update_msg.fw_total_len, update_msg.fw_total_len/1024); + memcpy(fw_head, >p_default_FW[0], FW_HEAD_LENGTH); + + //check firmware legality + fw_checksum = 0; + for(i=0; i< update_msg.fw_total_len; i+=2) + { + fw_checksum += (gtp_default_FW[FW_HEAD_LENGTH + i] << 8) + gtp_default_FW[FW_HEAD_LENGTH + i + 1]; + } + + GTP_DEBUG("firmware checksum:%x", fw_checksum&0xFFFF); + if (fw_checksum&0xFFFF) + { + GTP_ERROR("Illegal firmware file."); + return FAIL; + } + got_file_flag = HEADER_FW_READY; + return SUCCESS; + #else + + #if GTP_AUTO_UPDATE_CFG + gup_search_file(AUTO_SEARCH_BIN | AUTO_SEARCH_CFG); + if (got_file_flag & CFG_FILE_READY) + { + ret = gup_update_config(i2c_connect_client); + if(ret <= 0) + { + GTP_ERROR("Update config failed."); + } + _CLOSE_FILE(update_msg.cfg_file); + msleep(500); //waiting config to be stored in FLASH. + } + #else + gup_search_file(AUTO_SEARCH_BIN); + #endif + + if ( !(got_file_flag & BIN_FILE_READY) ) + { + GTP_ERROR("No bin file for fw update"); + return FAIL; + } + #endif + +#else + { + GTP_ERROR("NULL file for firmware update"); + return FAIL; + } +#endif + } + + update_msg.old_fs = get_fs(); + set_fs(KERNEL_DS); + + update_msg.file->f_op->llseek(update_msg.file, 0, SEEK_SET); + update_msg.fw_total_len = update_msg.file->f_op->llseek(update_msg.file, 0, SEEK_END); + if (update_msg.fw_total_len < (FW_HEAD_LENGTH + FW_SECTION_LENGTH*4+FW_DSP_ISP_LENGTH+FW_DSP_LENGTH+FW_BOOT_LENGTH)) + { + GTP_ERROR("INVALID bin file(size: %d), update aborted.", update_msg.fw_total_len); + return FAIL; + } + + update_msg.fw_total_len -= FW_HEAD_LENGTH; + + GTP_DEBUG("Bin firmware actual size: %d(%dK)", update_msg.fw_total_len, update_msg.fw_total_len/1024); + + update_msg.file->f_op->llseek(update_msg.file, 0, SEEK_SET); + ret = update_msg.file->f_op->read(update_msg.file, (char*)buf, FW_HEAD_LENGTH, &update_msg.file->f_pos); + if (ret < 0) + { + GTP_ERROR("Read firmware head in update file error."); + return FAIL; + } + + memcpy(fw_head, buf, FW_HEAD_LENGTH); + + //check firmware legality + fw_checksum = 0; + for(i=0; if_op->read(update_msg.file, (char*)buf, 2, &update_msg.file->f_pos); + if (ret < 0) + { + GTP_ERROR("Read firmware file error."); + return FAIL; + } + //GTP_DEBUG("BUF[0]:%x", buf[0]); + temp = (buf[0]<<8) + buf[1]; + fw_checksum += temp; + } + + GTP_DEBUG("firmware checksum:%x", fw_checksum&0xFFFF); + if(fw_checksum&0xFFFF) + { + GTP_ERROR("Illegal firmware file."); + return FAIL; + } + + return SUCCESS; +} + +static u8 gup_burn_proc(struct i2c_client *client, u8 *burn_buf, u16 start_addr, u16 total_length) +{ + s32 ret = 0; + u16 burn_addr = start_addr; + u16 frame_length = 0; + u16 burn_length = 0; + u8 wr_buf[PACK_SIZE + GTP_ADDR_LENGTH]; + u8 rd_buf[PACK_SIZE + GTP_ADDR_LENGTH]; + u8 retry = 0; + + GTP_DEBUG("Begin burn %dk data to addr 0x%x", (total_length/1024), start_addr); + if (!burn_buf) + return FAIL; + while(burn_length < total_length) + { + GTP_DEBUG("B/T:%04d/%04d", burn_length, total_length); + frame_length = ((total_length - burn_length) > PACK_SIZE) ? PACK_SIZE : (total_length - burn_length); + wr_buf[0] = (u8)(burn_addr>>8); + rd_buf[0] = wr_buf[0]; + wr_buf[1] = (u8)burn_addr; + rd_buf[1] = wr_buf[1]; + memcpy(&wr_buf[GTP_ADDR_LENGTH], &burn_buf[burn_length], frame_length); + + for(retry = 0; retry < MAX_FRAME_CHECK_TIME; retry++) + { + ret = gup_i2c_write(client, wr_buf, GTP_ADDR_LENGTH + frame_length); + if(ret <= 0) + { + GTP_ERROR("Write frame data i2c error."); + continue; + } + ret = gup_i2c_read(client, rd_buf, GTP_ADDR_LENGTH + frame_length); + if(ret <= 0) + { + GTP_ERROR("Read back frame data i2c error."); + continue; + } + + if(memcmp(&wr_buf[GTP_ADDR_LENGTH], &rd_buf[GTP_ADDR_LENGTH], frame_length)) + { + GTP_ERROR("Check frame data fail,not equal."); + GTP_DEBUG("write array:"); + GTP_DEBUG_ARRAY(&wr_buf[GTP_ADDR_LENGTH], frame_length); + GTP_DEBUG("read array:"); + GTP_DEBUG_ARRAY(&rd_buf[GTP_ADDR_LENGTH], frame_length); + continue; + } + else + { + //GTP_DEBUG("Check frame data success."); + break; + } + } + if(retry >= MAX_FRAME_CHECK_TIME) + { + GTP_ERROR("Burn frame data time out,exit."); + return FAIL; + } + burn_length += frame_length; + burn_addr += frame_length; + } + return SUCCESS; +} + +static u8 gup_load_section_file(u8 *buf, u32 offset, u16 length, u8 set_or_end) +{ +#if (GTP_AUTO_UPDATE && GTP_HEADER_FW_UPDATE) + if (got_file_flag == HEADER_FW_READY) + { + if(SEEK_SET == set_or_end) + { + memcpy(buf, >p_default_FW[FW_HEAD_LENGTH + offset], length); + } + else //seek end + { + memcpy(buf, >p_default_FW[update_msg.fw_total_len + FW_HEAD_LENGTH - offset], length); + } + return SUCCESS; + } +#endif + { + s32 ret = 0; + + if ( (update_msg.file == NULL) || IS_ERR(update_msg.file)) + { + GTP_ERROR("cannot find update file,load section file fail."); + return FAIL; + } + + if(SEEK_SET == set_or_end) + { + update_msg.file->f_pos = FW_HEAD_LENGTH + offset; + } + else //seek end + { + update_msg.file->f_pos = update_msg.fw_total_len + FW_HEAD_LENGTH - offset; + } + + ret = update_msg.file->f_op->read(update_msg.file, (char *)buf, length, &update_msg.file->f_pos); + + if (ret < 0) + { + GTP_ERROR("Read update file fail."); + return FAIL; + } + + return SUCCESS; + } +} + +static u8 gup_recall_check(struct i2c_client *client, u8* chk_src, u16 start_rd_addr, u16 chk_length) +{ + u8 rd_buf[PACK_SIZE + GTP_ADDR_LENGTH]; + s32 ret = 0; + u16 recall_addr = start_rd_addr; + u16 recall_length = 0; + u16 frame_length = 0; + + while(recall_length < chk_length) + { + frame_length = ((chk_length - recall_length) > PACK_SIZE) ? PACK_SIZE : (chk_length - recall_length); + ret = gup_get_ic_msg(client, recall_addr, rd_buf, frame_length); + if(ret <= 0) + { + GTP_ERROR("recall i2c error,exit"); + return FAIL; + } + + if(memcmp(&rd_buf[GTP_ADDR_LENGTH], &chk_src[recall_length], frame_length)) + { + GTP_ERROR("Recall frame data fail,not equal."); + GTP_DEBUG("chk_src array:"); + GTP_DEBUG_ARRAY(&chk_src[recall_length], frame_length); + GTP_DEBUG("recall array:"); + GTP_DEBUG_ARRAY(&rd_buf[GTP_ADDR_LENGTH], frame_length); + return FAIL; + } + + recall_length += frame_length; + recall_addr += frame_length; + } + GTP_DEBUG("Recall check %dk firmware success.", (chk_length/1024)); + + return SUCCESS; +} + +static u8 gup_burn_fw_section(struct i2c_client *client, u8 *fw_section, u16 start_addr, u8 bank_cmd ) +{ + s32 ret = 0; + u8 rd_buf[5]; + + //step1:hold ss51 & dsp + ret = gup_set_ic_msg(client, _rRW_MISCTL__SWRST_B0_, 0x0C); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_section]hold ss51 & dsp fail."); + return FAIL; + } + + //step2:set scramble + ret = gup_set_ic_msg(client, _rRW_MISCTL__BOOT_OPT_B0_, 0x00); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_section]set scramble fail."); + return FAIL; + } + + //step3:select bank + ret = gup_set_ic_msg(client, _bRW_MISCTL__SRAM_BANK, (bank_cmd >> 4)&0x0F); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_section]select bank %d fail.", (bank_cmd >> 4)&0x0F); + return FAIL; + } + + //step4:enable accessing code + ret = gup_set_ic_msg(client, _bRW_MISCTL__MEM_CD_EN, 0x01); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_section]enable accessing code fail."); + return FAIL; + } + + //step5:burn 8k fw section + ret = gup_burn_proc(client, fw_section, start_addr, FW_SECTION_LENGTH); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_section]burn fw_section fail."); + return FAIL; + } + + //step6:hold ss51 & release dsp + ret = gup_set_ic_msg(client, _rRW_MISCTL__SWRST_B0_, 0x04); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_section]hold ss51 & release dsp fail."); + return FAIL; + } + //must delay + msleep(1); + + //step7:send burn cmd to move data to flash from sram + ret = gup_set_ic_msg(client, _rRW_MISCTL__BOOT_CTL_, bank_cmd&0x0f); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_section]send burn cmd fail."); + return FAIL; + } + GTP_DEBUG("[burn_fw_section]Wait for the burn is complete......"); + do{ + ret = gup_get_ic_msg(client, _rRW_MISCTL__BOOT_CTL_, rd_buf, 1); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_section]Get burn state fail"); + return FAIL; + } + msleep(10); + //GTP_DEBUG("[burn_fw_section]Get burn state:%d.", rd_buf[GTP_ADDR_LENGTH]); + }while(rd_buf[GTP_ADDR_LENGTH]); + + //step8:select bank + ret = gup_set_ic_msg(client, _bRW_MISCTL__SRAM_BANK, (bank_cmd >> 4)&0x0F); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_section]select bank %d fail.", (bank_cmd >> 4)&0x0F); + return FAIL; + } + + //step9:enable accessing code + ret = gup_set_ic_msg(client, _bRW_MISCTL__MEM_CD_EN, 0x01); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_section]enable accessing code fail."); + return FAIL; + } + + //step10:recall 8k fw section + ret = gup_recall_check(client, fw_section, start_addr, FW_SECTION_LENGTH); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_section]recall check %dk firmware fail.", FW_SECTION_LENGTH/1024); + return FAIL; + } + + //step11:disable accessing code + ret = gup_set_ic_msg(client, _bRW_MISCTL__MEM_CD_EN, 0x00); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_section]disable accessing code fail."); + return FAIL; + } + + return SUCCESS; +} + +static u8 gup_burn_dsp_isp(struct i2c_client *client) +{ + s32 ret = 0; + u8* fw_dsp_isp = NULL; + u8 retry = 0; + + GTP_INFO("[burn_dsp_isp]Begin burn dsp isp---->>"); + + //step1:alloc memory + GTP_DEBUG("[burn_dsp_isp]step1:alloc memory"); + while(retry++ < 5) + { + fw_dsp_isp = (u8*)kzalloc(FW_DSP_ISP_LENGTH, GFP_KERNEL); + if(fw_dsp_isp == NULL) + { + continue; + } + else + { + GTP_INFO("[burn_dsp_isp]Alloc %dk byte memory success.", (FW_DSP_ISP_LENGTH/1024)); + break; + } + } + if(retry >= 5) + { + GTP_ERROR("[burn_dsp_isp]Alloc memory fail,exit."); + return FAIL; + } + + //step2:load dsp isp file data + GTP_DEBUG("[burn_dsp_isp]step2:load dsp isp file data"); + ret = gup_load_section_file(fw_dsp_isp, FW_DSP_ISP_LENGTH, FW_DSP_ISP_LENGTH, SEEK_END); + if(FAIL == ret) + { + GTP_ERROR("[burn_dsp_isp]load firmware dsp_isp fail."); + goto exit_burn_dsp_isp; + } + + //step3:disable wdt,clear cache enable + GTP_DEBUG("[burn_dsp_isp]step3:disable wdt,clear cache enable"); + ret = gup_set_ic_msg(client, _bRW_MISCTL__TMR0_EN, 0x00); + if(ret <= 0) + { + GTP_ERROR("[burn_dsp_isp]disable wdt fail."); + ret = FAIL; + goto exit_burn_dsp_isp; + } + ret = gup_set_ic_msg(client, _bRW_MISCTL__CACHE_EN, 0x00); + if(ret <= 0) + { + GTP_ERROR("[burn_dsp_isp]clear cache enable fail."); + ret = FAIL; + goto exit_burn_dsp_isp; + } + + //step4:hold ss51 & dsp + GTP_DEBUG("[burn_dsp_isp]step4:hold ss51 & dsp"); + ret = gup_set_ic_msg(client, _rRW_MISCTL__SWRST_B0_, 0x0C); + if(ret <= 0) + { + GTP_ERROR("[burn_dsp_isp]hold ss51 & dsp fail."); + ret = FAIL; + goto exit_burn_dsp_isp; + } + + //step5:set boot from sram + GTP_DEBUG("[burn_dsp_isp]step5:set boot from sram"); + ret = gup_set_ic_msg(client, _rRW_MISCTL__BOOTCTL_B0_, 0x02); + if(ret <= 0) + { + GTP_ERROR("[burn_dsp_isp]set boot from sram fail."); + ret = FAIL; + goto exit_burn_dsp_isp; + } + + //step6:software reboot + GTP_DEBUG("[burn_dsp_isp]step6:software reboot"); + ret = gup_set_ic_msg(client, _bWO_MISCTL__CPU_SWRST_PULSE, 0x01); + if(ret <= 0) + { + GTP_ERROR("[burn_dsp_isp]software reboot fail."); + ret = FAIL; + goto exit_burn_dsp_isp; + } + + //step7:select bank2 + GTP_DEBUG("[burn_dsp_isp]step7:select bank2"); + ret = gup_set_ic_msg(client, _bRW_MISCTL__SRAM_BANK, 0x02); + if(ret <= 0) + { + GTP_ERROR("[burn_dsp_isp]select bank2 fail."); + ret = FAIL; + goto exit_burn_dsp_isp; + } + + //step8:enable accessing code + GTP_DEBUG("[burn_dsp_isp]step8:enable accessing code"); + ret = gup_set_ic_msg(client, _bRW_MISCTL__MEM_CD_EN, 0x01); + if(ret <= 0) + { + GTP_ERROR("[burn_dsp_isp]enable accessing code fail."); + ret = FAIL; + goto exit_burn_dsp_isp; + } + + //step9:burn 4k dsp_isp + GTP_DEBUG("[burn_dsp_isp]step9:burn 4k dsp_isp"); + ret = gup_burn_proc(client, fw_dsp_isp, 0xC000, FW_DSP_ISP_LENGTH); + if(FAIL == ret) + { + GTP_ERROR("[burn_dsp_isp]burn dsp_isp fail."); + goto exit_burn_dsp_isp; + } + + //step10:set scramble + GTP_DEBUG("[burn_dsp_isp]step10:set scramble"); + ret = gup_set_ic_msg(client, _rRW_MISCTL__BOOT_OPT_B0_, 0x00); + if(ret <= 0) + { + GTP_ERROR("[burn_dsp_isp]set scramble fail."); + ret = FAIL; + goto exit_burn_dsp_isp; + } + update_msg.fw_burned_len += FW_DSP_ISP_LENGTH; + GTP_DEBUG("[burn_dsp_isp]Burned length:%d", update_msg.fw_burned_len); + ret = SUCCESS; + +exit_burn_dsp_isp: + kfree(fw_dsp_isp); + return ret; +} + +static u8 gup_burn_fw_ss51(struct i2c_client *client) +{ + u8* fw_ss51 = NULL; + u8 retry = 0; + s32 ret = 0; + + GTP_INFO("[burn_fw_ss51]Begin burn ss51 firmware---->>"); + + //step1:alloc memory + GTP_DEBUG("[burn_fw_ss51]step1:alloc memory"); + while(retry++ < 5) + { + fw_ss51 = (u8*)kzalloc(FW_SECTION_LENGTH, GFP_KERNEL); + if(fw_ss51 == NULL) + { + continue; + } + else + { + GTP_DEBUG("[burn_fw_ss51]Alloc %dk byte memory success.", (FW_SECTION_LENGTH / 1024)); + break; + } + } + if(retry >= 5) + { + GTP_ERROR("[burn_fw_ss51]Alloc memory fail,exit."); + return FAIL; + } + + //step2:load ss51 firmware section 1 file data +// GTP_DEBUG("[burn_fw_ss51]step2:load ss51 firmware section 1 file data"); +// ret = gup_load_section_file(fw_ss51, 0, FW_SECTION_LENGTH, SEEK_SET); +// if(FAIL == ret) +// { +// GTP_ERROR("[burn_fw_ss51]load ss51 firmware section 1 fail."); +// goto exit_burn_fw_ss51; +// } + + GTP_INFO("[burn_fw_ss51]Reset first 8K of ss51 to 0xFF."); + GTP_DEBUG("[burn_fw_ss51]step2: reset bank0 0xC000~0xD000"); + memset(fw_ss51, 0xFF, FW_SECTION_LENGTH); + + //step3:clear control flag + GTP_DEBUG("[burn_fw_ss51]step3:clear control flag"); + ret = gup_set_ic_msg(client, _rRW_MISCTL__BOOT_CTL_, 0x00); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_ss51]clear control flag fail."); + ret = FAIL; + goto exit_burn_fw_ss51; + } + + //step4:burn ss51 firmware section 1 + GTP_DEBUG("[burn_fw_ss51]step4:burn ss51 firmware section 1"); + ret = gup_burn_fw_section(client, fw_ss51, 0xC000, 0x01); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_ss51]burn ss51 firmware section 1 fail."); + goto exit_burn_fw_ss51; + } + + //step5:load ss51 firmware section 2 file data + GTP_DEBUG("[burn_fw_ss51]step5:load ss51 firmware section 2 file data"); + ret = gup_load_section_file(fw_ss51, FW_SECTION_LENGTH, FW_SECTION_LENGTH, SEEK_SET); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_ss51]load ss51 firmware section 2 fail."); + goto exit_burn_fw_ss51; + } + + //step6:burn ss51 firmware section 2 + GTP_DEBUG("[burn_fw_ss51]step6:burn ss51 firmware section 2"); + ret = gup_burn_fw_section(client, fw_ss51, 0xE000, 0x02); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_ss51]burn ss51 firmware section 2 fail."); + goto exit_burn_fw_ss51; + } + + //step7:load ss51 firmware section 3 file data + GTP_DEBUG("[burn_fw_ss51]step7:load ss51 firmware section 3 file data"); + ret = gup_load_section_file(fw_ss51, 2 * FW_SECTION_LENGTH, FW_SECTION_LENGTH, SEEK_SET); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_ss51]load ss51 firmware section 3 fail."); + goto exit_burn_fw_ss51; + } + + //step8:burn ss51 firmware section 3 + GTP_DEBUG("[burn_fw_ss51]step8:burn ss51 firmware section 3"); + ret = gup_burn_fw_section(client, fw_ss51, 0xC000, 0x13); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_ss51]burn ss51 firmware section 3 fail."); + goto exit_burn_fw_ss51; + } + + //step9:load ss51 firmware section 4 file data + GTP_DEBUG("[burn_fw_ss51]step9:load ss51 firmware section 4 file data"); + ret = gup_load_section_file(fw_ss51, 3 * FW_SECTION_LENGTH, FW_SECTION_LENGTH, SEEK_SET); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_ss51]load ss51 firmware section 4 fail."); + goto exit_burn_fw_ss51; + } + + //step10:burn ss51 firmware section 4 + GTP_DEBUG("[burn_fw_ss51]step10:burn ss51 firmware section 4"); + ret = gup_burn_fw_section(client, fw_ss51, 0xE000, 0x14); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_ss51]burn ss51 firmware section 4 fail."); + goto exit_burn_fw_ss51; + } + + update_msg.fw_burned_len += (FW_SECTION_LENGTH*4); + GTP_DEBUG("[burn_fw_ss51]Burned length:%d", update_msg.fw_burned_len); + ret = SUCCESS; + +exit_burn_fw_ss51: + kfree(fw_ss51); + return ret; +} + +static u8 gup_burn_fw_dsp(struct i2c_client *client) +{ + s32 ret = 0; + u8* fw_dsp = NULL; + u8 retry = 0; + u8 rd_buf[5]; + + GTP_INFO("[burn_fw_dsp]Begin burn dsp firmware---->>"); + //step1:alloc memory + GTP_DEBUG("[burn_fw_dsp]step1:alloc memory"); + while(retry++ < 5) + { + fw_dsp = (u8*)kzalloc(FW_DSP_LENGTH, GFP_KERNEL); + if(fw_dsp == NULL) + { + continue; + } + else + { + GTP_DEBUG("[burn_fw_dsp]Alloc %dk byte memory success.", (FW_SECTION_LENGTH / 1024)); + break; + } + } + if(retry >= 5) + { + GTP_ERROR("[burn_fw_dsp]Alloc memory fail,exit."); + return FAIL; + } + + //step2:load firmware dsp + GTP_DEBUG("[burn_fw_dsp]step2:load firmware dsp"); + ret = gup_load_section_file(fw_dsp, 4 * FW_SECTION_LENGTH, FW_DSP_LENGTH, SEEK_SET); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_dsp]load firmware dsp fail."); + goto exit_burn_fw_dsp; + } + + //step3:select bank3 + GTP_DEBUG("[burn_fw_dsp]step3:select bank3"); + ret = gup_set_ic_msg(client, _bRW_MISCTL__SRAM_BANK, 0x03); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_dsp]select bank3 fail."); + ret = FAIL; + goto exit_burn_fw_dsp; + } + + //step4:hold ss51 & dsp + GTP_DEBUG("[burn_fw_dsp]step4:hold ss51 & dsp"); + ret = gup_set_ic_msg(client, _rRW_MISCTL__SWRST_B0_, 0x0C); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_dsp]hold ss51 & dsp fail."); + ret = FAIL; + goto exit_burn_fw_dsp; + } + + //step5:set scramble + GTP_DEBUG("[burn_fw_dsp]step5:set scramble"); + ret = gup_set_ic_msg(client, _rRW_MISCTL__BOOT_OPT_B0_, 0x00); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_dsp]set scramble fail."); + ret = FAIL; + goto exit_burn_fw_dsp; + } + + //step6:release ss51 & dsp + GTP_DEBUG("[burn_fw_dsp]step6:release ss51 & dsp"); + ret = gup_set_ic_msg(client, _rRW_MISCTL__SWRST_B0_, 0x04); //20121211 + if(ret <= 0) + { + GTP_ERROR("[burn_fw_dsp]release ss51 & dsp fail."); + ret = FAIL; + goto exit_burn_fw_dsp; + } + //must delay + msleep(1); + + //step7:burn 4k dsp firmware + GTP_DEBUG("[burn_fw_dsp]step7:burn 4k dsp firmware"); + ret = gup_burn_proc(client, fw_dsp, 0x9000, FW_DSP_LENGTH); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_dsp]burn fw_section fail."); + goto exit_burn_fw_dsp; + } + + //step8:send burn cmd to move data to flash from sram + GTP_DEBUG("[burn_fw_dsp]step8:send burn cmd to move data to flash from sram"); + ret = gup_set_ic_msg(client, _rRW_MISCTL__BOOT_CTL_, 0x05); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_dsp]send burn cmd fail."); + goto exit_burn_fw_dsp; + } + GTP_DEBUG("[burn_fw_dsp]Wait for the burn is complete......"); + do{ + ret = gup_get_ic_msg(client, _rRW_MISCTL__BOOT_CTL_, rd_buf, 1); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_dsp]Get burn state fail"); + goto exit_burn_fw_dsp; + } + msleep(10); + //GTP_DEBUG("[burn_fw_dsp]Get burn state:%d.", rd_buf[GTP_ADDR_LENGTH]); + }while(rd_buf[GTP_ADDR_LENGTH]); + + //step9:recall check 4k dsp firmware + GTP_DEBUG("[burn_fw_dsp]step9:recall check 4k dsp firmware"); + ret = gup_recall_check(client, fw_dsp, 0x9000, FW_DSP_LENGTH); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_dsp]recall check 4k dsp firmware fail."); + goto exit_burn_fw_dsp; + } + + update_msg.fw_burned_len += FW_DSP_LENGTH; + GTP_DEBUG("[burn_fw_dsp]Burned length:%d", update_msg.fw_burned_len); + ret = SUCCESS; + +exit_burn_fw_dsp: + kfree(fw_dsp); + return ret; +} + +static u8 gup_burn_fw_boot(struct i2c_client *client) +{ + s32 ret = 0; + u8* fw_boot = NULL; + u8 retry = 0; + u8 rd_buf[5]; + + GTP_INFO("[burn_fw_boot]Begin burn bootloader firmware---->>"); + + //step1:Alloc memory + GTP_DEBUG("[burn_fw_boot]step1:Alloc memory"); + while(retry++ < 5) + { + fw_boot = (u8*)kzalloc(FW_BOOT_LENGTH, GFP_KERNEL); + if(fw_boot == NULL) + { + continue; + } + else + { + GTP_DEBUG("[burn_fw_boot]Alloc %dk byte memory success.", (FW_BOOT_LENGTH/1024)); + break; + } + } + if(retry >= 5) + { + GTP_ERROR("[burn_fw_boot]Alloc memory fail,exit."); + return FAIL; + } + + //step2:load firmware bootloader + GTP_DEBUG("[burn_fw_boot]step2:load firmware bootloader"); + ret = gup_load_section_file(fw_boot, (4 * FW_SECTION_LENGTH + FW_DSP_LENGTH), FW_BOOT_LENGTH, SEEK_SET); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_boot]load firmware bootcode fail."); + goto exit_burn_fw_boot; + } + + //step3:hold ss51 & dsp + GTP_DEBUG("[burn_fw_boot]step3:hold ss51 & dsp"); + ret = gup_set_ic_msg(client, _rRW_MISCTL__SWRST_B0_, 0x0C); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_boot]hold ss51 & dsp fail."); + ret = FAIL; + goto exit_burn_fw_boot; + } + + //step4:set scramble + GTP_DEBUG("[burn_fw_boot]step4:set scramble"); + ret = gup_set_ic_msg(client, _rRW_MISCTL__BOOT_OPT_B0_, 0x00); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_boot]set scramble fail."); + ret = FAIL; + goto exit_burn_fw_boot; + } + + //step5:hold ss51 & release dsp + GTP_DEBUG("[burn_fw_boot]step5:hold ss51 & release dsp"); + ret = gup_set_ic_msg(client, _rRW_MISCTL__SWRST_B0_, 0x04); //20121211 + if(ret <= 0) + { + GTP_ERROR("[burn_fw_boot]release ss51 & dsp fail."); + ret = FAIL; + goto exit_burn_fw_boot; + } + //must delay + msleep(1); + + //step6:select bank3 + GTP_DEBUG("[burn_fw_boot]step6:select bank3"); + ret = gup_set_ic_msg(client, _bRW_MISCTL__SRAM_BANK, 0x03); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_boot]select bank3 fail."); + ret = FAIL; + goto exit_burn_fw_boot; + } + + //step6:burn 2k bootloader firmware + GTP_DEBUG("[burn_fw_boot]step6:burn 2k bootloader firmware"); + ret = gup_burn_proc(client, fw_boot, 0x9000, FW_BOOT_LENGTH); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_boot]burn fw_boot fail."); + goto exit_burn_fw_boot; + } + + //step7:send burn cmd to move data to flash from sram + GTP_DEBUG("[burn_fw_boot]step7:send burn cmd to move data to flash from sram"); + ret = gup_set_ic_msg(client, _rRW_MISCTL__BOOT_CTL_, 0x06); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_boot]send burn cmd fail."); + goto exit_burn_fw_boot; + } + GTP_DEBUG("[burn_fw_boot]Wait for the burn is complete......"); + do{ + ret = gup_get_ic_msg(client, _rRW_MISCTL__BOOT_CTL_, rd_buf, 1); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_boot]Get burn state fail"); + goto exit_burn_fw_boot; + } + msleep(10); + //GTP_DEBUG("[burn_fw_boot]Get burn state:%d.", rd_buf[GTP_ADDR_LENGTH]); + }while(rd_buf[GTP_ADDR_LENGTH]); + + //step8:recall check 2k bootloader firmware + GTP_DEBUG("[burn_fw_boot]step8:recall check 2k bootloader firmware"); + ret = gup_recall_check(client, fw_boot, 0x9000, FW_BOOT_LENGTH); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_boot]recall check 2k bootcode firmware fail."); + goto exit_burn_fw_boot; + } + + update_msg.fw_burned_len += FW_BOOT_LENGTH; + GTP_DEBUG("[burn_fw_boot]Burned length:%d", update_msg.fw_burned_len); + ret = SUCCESS; + +exit_burn_fw_boot: + kfree(fw_boot); + return ret; +} +static u8 gup_burn_fw_boot_isp(struct i2c_client *client) +{ + s32 ret = 0; + u8* fw_boot_isp = NULL; + u8 retry = 0; + u8 rd_buf[5]; + + if(update_msg.fw_burned_len >= update_msg.fw_total_len) + { + GTP_DEBUG("No need to upgrade the boot_isp code!"); + return SUCCESS; + } + GTP_INFO("[burn_fw_boot_isp]Begin burn boot_isp firmware---->>"); + + //step1:Alloc memory + GTP_DEBUG("[burn_fw_boot_isp]step1:Alloc memory"); + while(retry++ < 5) + { + fw_boot_isp = (u8*)kzalloc(FW_BOOT_ISP_LENGTH, GFP_KERNEL); + if(fw_boot_isp == NULL) + { + continue; + } + else + { + GTP_DEBUG("[burn_fw_boot_isp]Alloc %dk byte memory success.", (FW_BOOT_ISP_LENGTH/1024)); + break; + } + } + if(retry >= 5) + { + GTP_ERROR("[burn_fw_boot_isp]Alloc memory fail,exit."); + return FAIL; + } + + //step2:load firmware bootloader + GTP_DEBUG("[burn_fw_boot_isp]step2:load firmware bootloader isp"); + //ret = gup_load_section_file(fw_boot_isp, (4*FW_SECTION_LENGTH+FW_DSP_LENGTH+FW_BOOT_LENGTH+FW_DSP_ISP_LENGTH), FW_BOOT_ISP_LENGTH, SEEK_SET); + ret = gup_load_section_file(fw_boot_isp, (update_msg.fw_burned_len - FW_DSP_ISP_LENGTH), FW_BOOT_ISP_LENGTH, SEEK_SET); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_boot_isp]load firmware boot_isp fail."); + goto exit_burn_fw_boot_isp; + } + + //step3:hold ss51 & dsp + GTP_DEBUG("[burn_fw_boot_isp]step3:hold ss51 & dsp"); + ret = gup_set_ic_msg(client, _rRW_MISCTL__SWRST_B0_, 0x0C); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_boot_isp]hold ss51 & dsp fail."); + ret = FAIL; + goto exit_burn_fw_boot_isp; + } + + //step4:set scramble + GTP_DEBUG("[burn_fw_boot_isp]step4:set scramble"); + ret = gup_set_ic_msg(client, _rRW_MISCTL__BOOT_OPT_B0_, 0x00); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_boot_isp]set scramble fail."); + ret = FAIL; + goto exit_burn_fw_boot_isp; + } + + + //step5:hold ss51 & release dsp + GTP_DEBUG("[burn_fw_boot_isp]step5:hold ss51 & release dsp"); + ret = gup_set_ic_msg(client, _rRW_MISCTL__SWRST_B0_, 0x04); //20121211 + if(ret <= 0) + { + GTP_ERROR("[burn_fw_boot_isp]release ss51 & dsp fail."); + ret = FAIL; + goto exit_burn_fw_boot_isp; + } + //must delay + msleep(1); + + //step6:select bank3 + GTP_DEBUG("[burn_fw_boot_isp]step6:select bank3"); + ret = gup_set_ic_msg(client, _bRW_MISCTL__SRAM_BANK, 0x03); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_boot_isp]select bank3 fail."); + ret = FAIL; + goto exit_burn_fw_boot_isp; + } + + //step7:burn 2k bootload_isp firmware + GTP_DEBUG("[burn_fw_boot_isp]step7:burn 2k bootloader firmware"); + ret = gup_burn_proc(client, fw_boot_isp, 0x9000, FW_BOOT_ISP_LENGTH); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_boot_isp]burn fw_section fail."); + goto exit_burn_fw_boot_isp; + } + + //step7:send burn cmd to move data to flash from sram + GTP_DEBUG("[burn_fw_boot_isp]step8:send burn cmd to move data to flash from sram"); + ret = gup_set_ic_msg(client, _rRW_MISCTL__BOOT_CTL_, 0x07); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_boot_isp]send burn cmd fail."); + goto exit_burn_fw_boot_isp; + } + GTP_DEBUG("[burn_fw_boot_isp]Wait for the burn is complete......"); + do{ + ret = gup_get_ic_msg(client, _rRW_MISCTL__BOOT_CTL_, rd_buf, 1); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_boot_isp]Get burn state fail"); + goto exit_burn_fw_boot_isp; + } + msleep(10); + //GTP_DEBUG("[burn_fw_boot_isp]Get burn state:%d.", rd_buf[GTP_ADDR_LENGTH]); + }while(rd_buf[GTP_ADDR_LENGTH]); + + //step8:recall check 2k bootload_isp firmware + GTP_DEBUG("[burn_fw_boot_isp]step9:recall check 2k bootloader firmware"); + ret = gup_recall_check(client, fw_boot_isp, 0x9000, FW_BOOT_ISP_LENGTH); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_boot_isp]recall check 2k bootcode_isp firmware fail."); + goto exit_burn_fw_boot_isp; + } + + update_msg.fw_burned_len += FW_BOOT_ISP_LENGTH; + GTP_DEBUG("[burn_fw_boot_isp]Burned length:%d", update_msg.fw_burned_len); + ret = SUCCESS; + +exit_burn_fw_boot_isp: + kfree(fw_boot_isp); + return ret; +} + +static u8 gup_burn_fw_link(struct i2c_client *client) +{ + s32 ret = 0; + u8* fw_link = NULL; + u8 retry = 0; + u32 offset; + + if(update_msg.fw_burned_len >= update_msg.fw_total_len) + { + GTP_DEBUG("No need to upgrade the link code!"); + return SUCCESS; + } + GTP_INFO("[burn_fw_link]Begin burn link firmware---->>"); + + //step1:Alloc memory + GTP_DEBUG("[burn_fw_link]step1:Alloc memory"); + while(retry++ < 5) + { + fw_link = (u8*)kzalloc(FW_SECTION_LENGTH, GFP_KERNEL); + if(fw_link == NULL) + { + continue; + } + else + { + GTP_DEBUG("[burn_fw_link]Alloc %dk byte memory success.", (FW_SECTION_LENGTH/1024)); + break; + } + } + if(retry >= 5) + { + GTP_ERROR("[burn_fw_link]Alloc memory fail,exit."); + return FAIL; + } + + //step2:load firmware link section 1 + GTP_DEBUG("[burn_fw_link]step2:load firmware link section 1"); + offset = update_msg.fw_burned_len - FW_DSP_ISP_LENGTH; + ret = gup_load_section_file(fw_link, offset, FW_SECTION_LENGTH, SEEK_SET); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_link]load firmware link section 1 fail."); + goto exit_burn_fw_link; + } + + //step3:burn link firmware section 1 + GTP_DEBUG("[burn_fw_link]step3:burn link firmware section 1"); + ret = gup_burn_fw_gwake_section(client, fw_link, 0x9000, FW_SECTION_LENGTH, 0x38); + + if (FAIL == ret) + { + GTP_ERROR("[burn_fw_link]burn link firmware section 1 fail."); + goto exit_burn_fw_link; + } + + //step4:load link firmware section 2 file data + GTP_DEBUG("[burn_fw_link]step4:load link firmware section 2 file data"); + offset += FW_SECTION_LENGTH; + ret = gup_load_section_file(fw_link, offset, FW_GLINK_LENGTH - FW_SECTION_LENGTH, SEEK_SET); + + if (FAIL == ret) + { + GTP_ERROR("[burn_fw_link]load link firmware section 2 fail."); + goto exit_burn_fw_link; + } + + //step5:burn link firmware section 2 + GTP_DEBUG("[burn_fw_link]step4:burn link firmware section 2"); + ret = gup_burn_fw_gwake_section(client, fw_link, 0x9000, FW_GLINK_LENGTH - FW_SECTION_LENGTH, 0x39); + + if (FAIL == ret) + { + GTP_ERROR("[burn_fw_link]burn link firmware section 2 fail."); + goto exit_burn_fw_link; + } + + update_msg.fw_burned_len += FW_GLINK_LENGTH; + GTP_DEBUG("[burn_fw_link]Burned length:%d", update_msg.fw_burned_len); + ret = SUCCESS; + +exit_burn_fw_link: + kfree(fw_link); + return ret; +} + +static u8 gup_burn_fw_gwake_section(struct i2c_client *client, u8 *fw_section, u16 start_addr, u32 len, u8 bank_cmd ) +{ + s32 ret = 0; + u8 rd_buf[5]; + + //step1:hold ss51 & dsp + ret = gup_set_ic_msg(client, _rRW_MISCTL__SWRST_B0_, 0x0C); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_app_section]hold ss51 & dsp fail."); + return FAIL; + } + + //step2:set scramble + ret = gup_set_ic_msg(client, _rRW_MISCTL__BOOT_OPT_B0_, 0x00); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_app_section]set scramble fail."); + return FAIL; + } + + //step3:hold ss51 & release dsp + ret = gup_set_ic_msg(client, _rRW_MISCTL__SWRST_B0_, 0x04); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_app_section]hold ss51 & release dsp fail."); + return FAIL; + } + //must delay + msleep(1); + + //step4:select bank + ret = gup_set_ic_msg(client, _bRW_MISCTL__SRAM_BANK, (bank_cmd >> 4)&0x0F); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_section]select bank %d fail.", (bank_cmd >> 4)&0x0F); + return FAIL; + } + + //step5:burn fw section + ret = gup_burn_proc(client, fw_section, start_addr, len); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_app_section]burn fw_section fail."); + return FAIL; + } + + //step6:send burn cmd to move data to flash from sram + ret = gup_set_ic_msg(client, _rRW_MISCTL__BOOT_CTL_, bank_cmd&0x0F); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_app_section]send burn cmd fail."); + return FAIL; + } + GTP_DEBUG("[burn_fw_section]Wait for the burn is complete......"); + do{ + ret = gup_get_ic_msg(client, _rRW_MISCTL__BOOT_CTL_, rd_buf, 1); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_app_section]Get burn state fail"); + return FAIL; + } + msleep(10); + //GTP_DEBUG("[burn_fw_app_section]Get burn state:%d.", rd_buf[GTP_ADDR_LENGTH]); + }while(rd_buf[GTP_ADDR_LENGTH]); + + //step7:recall fw section + ret = gup_recall_check(client, fw_section, start_addr, len); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_app_section]recall check %dk firmware fail.", len/1024); + return FAIL; + } + + return SUCCESS; +} + +static u8 gup_burn_fw_gwake(struct i2c_client *client) +{ + u8* fw_gwake = NULL; + u8 retry = 0; + s32 ret = 0; + u16 start_index = 4*FW_SECTION_LENGTH+FW_DSP_LENGTH+FW_BOOT_LENGTH + FW_BOOT_ISP_LENGTH + FW_GLINK_LENGTH; // 32 + 4 + 2 + 4 = 42K + //u16 start_index; + + if(update_msg.fw_burned_len >= update_msg.fw_total_len) + { + GTP_DEBUG("No need to upgrade the gwake code!"); + return SUCCESS; + } + //start_index = update_msg.fw_burned_len - FW_DSP_ISP_LENGTH; + GTP_INFO("[burn_fw_gwake]Begin burn gwake firmware---->>"); + + //step1:alloc memory + GTP_DEBUG("[burn_fw_gwake]step1:alloc memory"); + while(retry++ < 5) + { + fw_gwake = (u8*)kzalloc(FW_SECTION_LENGTH, GFP_KERNEL); + if(fw_gwake == NULL) + { + continue; + } + else + { + GTP_DEBUG("[burn_fw_gwake]Alloc %dk byte memory success.", (FW_SECTION_LENGTH/1024)); + break; + } + } + if(retry >= 5) + { + GTP_ERROR("[burn_fw_gwake]Alloc memory fail,exit."); + return FAIL; + } + + //clear control flag + ret = gup_set_ic_msg(client,_rRW_MISCTL__BOOT_CTL_, 0x00); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_finish]clear control flag fail."); + goto exit_burn_fw_gwake; + } + + //step2:load app_code firmware section 1 file data + GTP_DEBUG("[burn_fw_gwake]step2:load app_code firmware section 1 file data"); + ret = gup_load_section_file(fw_gwake, start_index, FW_SECTION_LENGTH, SEEK_SET); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_gwake]load app_code firmware section 1 fail."); + goto exit_burn_fw_gwake; + } + + //step3:burn app_code firmware section 1 + GTP_DEBUG("[burn_fw_gwake]step3:burn app_code firmware section 1"); + ret = gup_burn_fw_gwake_section(client, fw_gwake, 0x9000, FW_SECTION_LENGTH, 0x3A); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_gwake]burn app_code firmware section 1 fail."); + goto exit_burn_fw_gwake; + } + + //step5:load app_code firmware section 2 file data + GTP_DEBUG("[burn_fw_gwake]step5:load app_code firmware section 2 file data"); + ret = gup_load_section_file(fw_gwake, start_index+FW_SECTION_LENGTH, FW_SECTION_LENGTH, SEEK_SET); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_gwake]load app_code firmware section 2 fail."); + goto exit_burn_fw_gwake; + } + + //step6:burn app_code firmware section 2 + GTP_DEBUG("[burn_fw_gwake]step6:burn app_code firmware section 2"); + ret = gup_burn_fw_gwake_section(client, fw_gwake, 0x9000, FW_SECTION_LENGTH, 0x3B); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_gwake]burn app_code firmware section 2 fail."); + goto exit_burn_fw_gwake; + } + + //step7:load app_code firmware section 3 file data + GTP_DEBUG("[burn_fw_gwake]step7:load app_code firmware section 3 file data"); + ret = gup_load_section_file(fw_gwake, start_index+2*FW_SECTION_LENGTH, FW_SECTION_LENGTH, SEEK_SET); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_gwake]load app_code firmware section 3 fail."); + goto exit_burn_fw_gwake; + } + + //step8:burn app_code firmware section 3 + GTP_DEBUG("[burn_fw_gwake]step8:burn app_code firmware section 3"); + ret = gup_burn_fw_gwake_section(client, fw_gwake, 0x9000, FW_SECTION_LENGTH, 0x3C); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_gwake]burn app_code firmware section 3 fail."); + goto exit_burn_fw_gwake; + } + + //step9:load app_code firmware section 4 file data + GTP_DEBUG("[burn_fw_gwake]step9:load app_code firmware section 4 file data"); + ret = gup_load_section_file(fw_gwake, start_index + 3*FW_SECTION_LENGTH, FW_SECTION_LENGTH, SEEK_SET); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_gwake]load app_code firmware section 4 fail."); + goto exit_burn_fw_gwake; + } + + //step10:burn app_code firmware section 4 + GTP_DEBUG("[burn_fw_gwake]step10:burn app_code firmware section 4"); + ret = gup_burn_fw_gwake_section(client, fw_gwake, 0x9000, FW_SECTION_LENGTH, 0x3D); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_gwake]burn app_code firmware section 4 fail."); + goto exit_burn_fw_gwake; + } + + //update_msg.fw_burned_len += FW_GWAKE_LENGTH; + GTP_DEBUG("[burn_fw_gwake]Burned length:%d", update_msg.fw_burned_len); + ret = SUCCESS; + +exit_burn_fw_gwake: + kfree(fw_gwake); + return ret; +} + +static u8 gup_burn_fw_finish(struct i2c_client *client) +{ + u8* fw_ss51 = NULL; + u8 retry = 0; + s32 ret = 0; + + GTP_INFO("[burn_fw_finish]burn first 8K of ss51 and finish update."); + //step1:alloc memory + GTP_DEBUG("[burn_fw_finish]step1:alloc memory"); + while(retry++ < 5) + { + fw_ss51 = (u8*)kzalloc(FW_SECTION_LENGTH, GFP_KERNEL); + if(fw_ss51 == NULL) + { + continue; + } + else + { + GTP_DEBUG("[burn_fw_finish]Alloc %dk byte memory success.", (FW_SECTION_LENGTH/1024)); + break; + } + } + if(retry >= 5) + { + GTP_ERROR("[burn_fw_finish]Alloc memory fail,exit."); + return FAIL; + } + + GTP_DEBUG("[burn_fw_finish]step2: burn ss51 first 8K."); + ret = gup_load_section_file(fw_ss51, 0, FW_SECTION_LENGTH, SEEK_SET); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_finish]load ss51 firmware section 1 fail."); + goto exit_burn_fw_finish; + } + + GTP_DEBUG("[burn_fw_finish]step3:clear control flag"); + ret = gup_set_ic_msg(client, _rRW_MISCTL__BOOT_CTL_, 0x00); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_finish]clear control flag fail."); + goto exit_burn_fw_finish; + } + + GTP_DEBUG("[burn_fw_finish]step4:burn ss51 firmware section 1"); + ret = gup_burn_fw_section(client, fw_ss51, 0xC000, 0x01); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_finish]burn ss51 firmware section 1 fail."); + goto exit_burn_fw_finish; + } + + //step11:enable download DSP code + GTP_DEBUG("[burn_fw_finish]step5:enable download DSP code "); + ret = gup_set_ic_msg(client, _rRW_MISCTL__BOOT_CTL_, 0x99); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_finish]enable download DSP code fail."); + goto exit_burn_fw_finish; + } + + //step12:release ss51 & hold dsp + GTP_DEBUG("[burn_fw_finish]step6:release ss51 & hold dsp"); + ret = gup_set_ic_msg(client, _rRW_MISCTL__SWRST_B0_, 0x08); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_finish]release ss51 & hold dsp fail."); + goto exit_burn_fw_finish; + } + + if (fw_ss51) + { + kfree(fw_ss51); + } + return SUCCESS; + +exit_burn_fw_finish: + if (fw_ss51) + { + kfree(fw_ss51); + } + return FAIL; +} +s32 gup_update_proc(void *dir) +{ + s32 ret = 0; + s32 update_ret = FAIL; + u8 retry = 0; + st_fw_head fw_head; + struct goodix_ts_data *ts = NULL; + + GTP_DEBUG("[update_proc]Begin update ......"); + + ts = i2c_get_clientdata(i2c_connect_client); + +#if GTP_AUTO_UPDATE + if (searching_file) + { + u8 timeout = 0; + searching_file = 0; // exit .bin update file searching + GTP_INFO("Exiting searching .bin update file..."); + while ((show_len != 200) && (show_len != 100) && (timeout++ < 100)) // wait for auto update quitted completely + { + msleep(100); + } + } +#endif + + show_len = 1; + total_len = 100; + +#if GTP_COMPATIBLE_MODE + if (CHIP_TYPE_GT9F == ts->chip_type) + { + return gup_fw_download_proc(dir, GTP_FL_FW_BURN); + } +#endif + + update_msg.file = NULL; + ret = gup_check_update_file(i2c_connect_client, &fw_head, (u8*)dir); //20121211 + if(FAIL == ret) + { + GTP_ERROR("[update_proc]check update file fail."); + goto file_fail; + } + + ret = gup_get_ic_fw_msg(i2c_connect_client); + if(FAIL == ret) + { + GTP_ERROR("[update_proc]get ic message fail."); + goto file_fail; + } + + ret = gup_enter_update_judge(&fw_head); + if(FAIL == ret) + { + GTP_ERROR("[update_proc]Check *.bin file fail."); + goto file_fail; + } + + ts->enter_update = 1; + gtp_irq_disable(ts); +#if GTP_ESD_PROTECT + gtp_esd_switch(ts->client, SWITCH_OFF); +#endif + ret = gup_enter_update_mode(i2c_connect_client); + if(FAIL == ret) + { + GTP_ERROR("[update_proc]enter update mode fail."); + goto update_fail; + } + + while(retry++ < 5) + { + show_len = 10; + total_len = 100; + update_msg.fw_burned_len = 0; + ret = gup_burn_dsp_isp(i2c_connect_client); + if(FAIL == ret) + { + GTP_ERROR("[update_proc]burn dsp isp fail."); + continue; + } + + show_len = 20; + ret = gup_burn_fw_gwake(i2c_connect_client); + if (FAIL == ret) + { + GTP_ERROR("[update_proc]burn app_code firmware fail."); + continue; + } + + show_len = 30; + ret = gup_burn_fw_ss51(i2c_connect_client); + if(FAIL == ret) + { + GTP_ERROR("[update_proc]burn ss51 firmware fail."); + continue; + } + + show_len = 40; + ret = gup_burn_fw_dsp(i2c_connect_client); + if(FAIL == ret) + { + GTP_ERROR("[update_proc]burn dsp firmware fail."); + continue; + } + + show_len = 50; + ret = gup_burn_fw_boot(i2c_connect_client); + if(FAIL == ret) + { + GTP_ERROR("[update_proc]burn bootloader firmware fail."); + continue; + } + show_len = 60; + + ret = gup_burn_fw_boot_isp(i2c_connect_client); + if (FAIL == ret) + { + GTP_ERROR("[update_proc]burn boot_isp firmware fail."); + continue; + } + + show_len = 70; + ret = gup_burn_fw_link(i2c_connect_client); + if (FAIL == ret) + { + GTP_ERROR("[update_proc]burn link firmware fail."); + continue; + } + + show_len = 80; + ret = gup_burn_fw_finish(i2c_connect_client); + if (FAIL == ret) + { + GTP_ERROR("[update_proc]burn finish fail."); + continue; + } + show_len = 90; + GTP_INFO("[update_proc]UPDATE SUCCESS."); + retry = 0; + break; + } + + if (retry >= 5) + { + GTP_ERROR("[update_proc]retry timeout,UPDATE FAIL."); + update_ret = FAIL; + } + else + { + update_ret = SUCCESS; + } + +update_fail: + GTP_DEBUG("[update_proc]leave update mode."); + gup_leave_update_mode(); + + msleep(100); + + if (SUCCESS == update_ret) + { + if (ts->fw_error) + { + GTP_INFO("firmware error auto update, resent config!"); + gup_init_panel(ts); + } + else + { + GTP_DEBUG("[update_proc]send config."); + ret = gtp_send_cfg(i2c_connect_client); + if (ret < 0) + { + GTP_ERROR("[update_proc]send config fail."); + } + else + { + msleep(100); + } + } + } + ts->enter_update = 0; + gtp_irq_enable(ts); + +#if GTP_ESD_PROTECT + gtp_esd_switch(ts->client, SWITCH_ON); +#endif + +file_fail: + if (update_msg.file && !IS_ERR(update_msg.file)) + { + if (update_msg.old_fs) + { + set_fs(update_msg.old_fs); + } + filp_close(update_msg.file, NULL); + } +#if (GTP_AUTO_UPDATE && GTP_AUTO_UPDATE_CFG && GTP_HEADER_FW_UPDATE) + if (NULL == dir) + { + gup_search_file(AUTO_SEARCH_CFG); + if (got_file_flag & CFG_FILE_READY) + { + ret = gup_update_config(i2c_connect_client); + if(ret <= 0) + { + GTP_ERROR("Update config failed."); + } + _CLOSE_FILE(update_msg.cfg_file); + msleep(500); //waiting config to be stored in FLASH. + } + } +#endif + + total_len = 100; + if (SUCCESS == update_ret) + { + show_len = 100; + return SUCCESS; + } + else + { + show_len = 200; + return FAIL; + } +} + +#if GTP_AUTO_UPDATE +u8 gup_init_update_proc(struct goodix_ts_data *ts) +{ + struct task_struct *thread = NULL; + + GTP_INFO("Ready to run update thread."); + +#if GTP_COMPATIBLE_MODE + if (CHIP_TYPE_GT9F == ts->chip_type) + { + thread = kthread_run(gup_update_proc, "update", "fl update"); + } + else +#endif + { + thread = kthread_run(gup_update_proc, (void*)NULL, "guitar_update"); + } + if (IS_ERR(thread)) + { + GTP_ERROR("Failed to create update thread.\n"); + return -1; + } + + return 0; +} +#endif + + +//************************** For GT9XXF Start ***********************// +#define FW_DOWNLOAD_LENGTH 0x4000 +#define FW_SS51_SECTION_LEN 0x2000 // 4 section, each 8k +#define FL_PACK_SIZE 1024 +#define GUP_FW_CHK_SIZE FL_PACK_SIZE //FL_PACK_SIZE + +#define FL_UPDATE_PATH "/data/_fl_update_.bin" +#define FL_UPDATE_PATH_SD "/sdcard/_fl_update_.bin" +//for clk cal +#define PULSE_LENGTH (200) +#define INIT_CLK_DAC (50) +#define MAX_CLK_DAC (120) +#define CLK_AVG_TIME (1) +#define MILLION 1000000 + +#define _wRW_MISCTL__RG_DMY 0x4282 +#define _bRW_MISCTL__RG_OSC_CALIB 0x4268 +#define _fRW_MISCTL__GIO0 0x41e9 +#define _fRW_MISCTL__GIO1 0x41ed +#define _fRW_MISCTL__GIO2 0x41f1 +#define _fRW_MISCTL__GIO3 0x41f5 +#define _fRW_MISCTL__GIO4 0x41f9 +#define _fRW_MISCTL__GIO5 0x41fd +#define _fRW_MISCTL__GIO6 0x4201 +#define _fRW_MISCTL__GIO7 0x4205 +#define _fRW_MISCTL__GIO8 0x4209 +#define _fRW_MISCTL__GIO9 0x420d +#define _fRW_MISCTL__MEA 0x41a0 +#define _bRW_MISCTL__MEA_MODE 0x41a1 +#define _wRW_MISCTL__MEA_MAX_NUM 0x41a4 +#define _dRO_MISCTL__MEA_VAL 0x41b0 +#define _bRW_MISCTL__MEA_SRCSEL 0x41a3 +#define _bRO_MISCTL__MEA_RDY 0x41a8 +#define _rRW_MISCTL__ANA_RXADC_B0_ 0x4250 +#define _bRW_MISCTL__RG_LDO_A18_PWD 0x426f +#define _bRW_MISCTL__RG_BG_PWD 0x426a +#define _bRW_MISCTL__RG_CLKGEN_PWD 0x4269 +#define _fRW_MISCTL__RG_RXADC_PWD 0x426a +#define _bRW_MISCTL__OSC_CK_SEL 0x4030 +#define _rRW_MISCTL_RG_DMY83 0x4283 +#define _rRW_MISCTL__GIO1CTL_B2_ 0x41ee +#define _rRW_MISCTL__GIO1CTL_B1_ 0x41ed + + +#if GTP_COMPATIBLE_MODE + +u8 i2c_opr_buf[GTP_ADDR_LENGTH + FL_PACK_SIZE] = {0}; +u8 chk_cmp_buf[FL_PACK_SIZE] = {0}; + +extern s32 gtp_fw_startup(struct i2c_client *client); +static u8 gup_download_fw_dsp(struct i2c_client *client, u8 dwn_mode); +static s32 gup_burn_fw_proc(struct i2c_client *client, u16 start_addr, s32 start_index, s32 burn_len); +static s32 gup_check_and_repair(struct i2c_client *client, u16 start_addr, s32 start_index, s32 chk_len); + + +u8 gup_check_fs_mounted(char *path_name) +{ + struct path root_path; + struct path path; + int err = -1; + err = kern_path("/", LOOKUP_FOLLOW, &root_path); + + if (err) + { + GTP_DEBUG("\"/\" NOT Mounted: %d", err); + return FAIL; + } + err = kern_path(path_name, LOOKUP_FOLLOW, &path); + + if (err) + { + GTP_DEBUG("%s NOT Mounted: %d", path_name, err); + err = FAIL; + goto exit_chk; + } + + if (path.mnt->mnt_sb == root_path.mnt->mnt_sb) { + err = FAIL; + } else { + err = SUCCESS; + } + + path_put(&path); +exit_chk: + path_put(&root_path); + return err; +} + +s32 i2c_write_bytes(struct i2c_client *client, u16 addr, u8 *buf, s32 len) +{ + s32 ret = 0; + s32 write_bytes = 0; + s32 retry = 0; + u8 *tx_buf = buf; + + while (len > 0) + { + i2c_opr_buf[0] = (u8)(addr >> 8); + i2c_opr_buf[1] = (u8)(addr & 0xFF); + if (len > FL_PACK_SIZE) + { + write_bytes = FL_PACK_SIZE; + } + else + { + write_bytes = len; + } + memcpy(i2c_opr_buf + 2, tx_buf, write_bytes); + for (retry = 0; retry < 5; ++retry) + { + ret = gup_i2c_write(client, i2c_opr_buf, write_bytes + GTP_ADDR_LENGTH); + if (ret == 1) + { + break; + } + } + if (retry >= 5) + { + GTP_ERROR("retry timeout, I2C write 0x%04X %d bytes failed!", addr, write_bytes); + return -1; + } + addr += write_bytes; + len -= write_bytes; + tx_buf += write_bytes; + } + + return 1; +} + +s32 i2c_read_bytes(struct i2c_client *client, u16 addr, u8 *buf, s32 len) +{ + s32 ret = 0; + s32 read_bytes = 0; + s32 retry = 0; + u8 *tx_buf = buf; + + while (len > 0) + { + i2c_opr_buf[0] = (u8)(addr >> 8); + i2c_opr_buf[1] = (u8)(addr & 0xFF); + if (len > FL_PACK_SIZE) + { + read_bytes = FL_PACK_SIZE; + } + else + { + read_bytes = len; + } + for (retry = 0; retry < 5; ++retry) + { + ret = gup_i2c_read(client, i2c_opr_buf, read_bytes + GTP_ADDR_LENGTH); + if (ret == 2) + { + break; + } + } + if (retry >= 5) + { + GTP_ERROR("retry timeout, I2C read 0x%04X %d bytes failed!", addr, read_bytes); + return -1; + } + memcpy(tx_buf, i2c_opr_buf + 2, read_bytes); + addr += read_bytes; + len -= read_bytes; + tx_buf += read_bytes; + } + return 2; +} + + + +// main clock calibration +// bit: 0~7, val: 0/1 +static void gup_bit_write(s32 addr, s32 bit, s32 val) +{ + u8 buf; + i2c_read_bytes(i2c_connect_client, addr, &buf, 1); + + buf = (buf & (~((u8)1 << bit))) | ((u8)val << bit); + + i2c_write_bytes(i2c_connect_client, addr, &buf, 1); +} + +static void gup_clk_count_init(s32 bCh, s32 bCNT) +{ + u8 buf; + + //_fRW_MISCTL__MEA_EN = 0; //Frequency measure enable + gup_bit_write(_fRW_MISCTL__MEA, 0, 0); + //_fRW_MISCTL__MEA_CLR = 1; //Frequency measure clear + gup_bit_write(_fRW_MISCTL__MEA, 1, 1); + //_bRW_MISCTL__MEA_MODE = 0; //Pulse mode + buf = 0; + i2c_write_bytes(i2c_connect_client, _bRW_MISCTL__MEA_MODE, &buf, 1); + //_bRW_MISCTL__MEA_SRCSEL = 8 + bCh; //From GIO1 + buf = 8 + bCh; + i2c_write_bytes(i2c_connect_client, _bRW_MISCTL__MEA_SRCSEL, &buf, 1); + //_wRW_MISCTL__MEA_MAX_NUM = bCNT; //Set the Measure Counts = 1 + buf = bCNT; + i2c_write_bytes(i2c_connect_client, _wRW_MISCTL__MEA_MAX_NUM, &buf, 1); + //_fRW_MISCTL__MEA_CLR = 0; //Frequency measure not clear + gup_bit_write(_fRW_MISCTL__MEA, 1, 0); + //_fRW_MISCTL__MEA_EN = 1; + gup_bit_write(_fRW_MISCTL__MEA, 0, 1); +} + +static u32 gup_clk_count_get(void) +{ + s32 ready = 0; + s32 temp; + s8 buf[4]; + + while ((ready == 0)) //Wait for measurement complete + { + i2c_read_bytes(i2c_connect_client, _bRO_MISCTL__MEA_RDY, buf, 1); + ready = buf[0]; + } + + msleep(50); + + //_fRW_MISCTL__MEA_EN = 0; + gup_bit_write(_fRW_MISCTL__MEA, 0, 0); + i2c_read_bytes(i2c_connect_client, _dRO_MISCTL__MEA_VAL, buf, 4); + GTP_DEBUG("Clk_count 0: %2X", buf[0]); + GTP_DEBUG("Clk_count 1: %2X", buf[1]); + GTP_DEBUG("Clk_count 2: %2X", buf[2]); + GTP_DEBUG("Clk_count 3: %2X", buf[3]); + + temp = (s32)buf[0] + ((s32)buf[1] << 8) + ((s32)buf[2] << 16) + ((s32)buf[3] << 24); + GTP_INFO("Clk_count : %d", temp); + return temp; +} +u8 gup_clk_dac_setting(int dac) +{ + s8 buf1, buf2; + + i2c_read_bytes(i2c_connect_client, _wRW_MISCTL__RG_DMY, &buf1, 1); + i2c_read_bytes(i2c_connect_client, _bRW_MISCTL__RG_OSC_CALIB, &buf2, 1); + + buf1 = (buf1 & 0xFFCF) | ((dac & 0x03) << 4); + buf2 = (dac >> 2) & 0x3f; + + i2c_write_bytes(i2c_connect_client, _wRW_MISCTL__RG_DMY, &buf1, 1); + i2c_write_bytes(i2c_connect_client, _bRW_MISCTL__RG_OSC_CALIB, &buf2, 1); + + return 0; +} + +static u8 gup_clk_calibration_pin_select(s32 bCh) +{ + s32 i2c_addr; + + switch (bCh) + { + case 0: + i2c_addr = _fRW_MISCTL__GIO0; + break; + + case 1: + i2c_addr = _fRW_MISCTL__GIO1; + break; + + case 2: + i2c_addr = _fRW_MISCTL__GIO2; + break; + + case 3: + i2c_addr = _fRW_MISCTL__GIO3; + break; + + case 4: + i2c_addr = _fRW_MISCTL__GIO4; + break; + + case 5: + i2c_addr = _fRW_MISCTL__GIO5; + break; + + case 6: + i2c_addr = _fRW_MISCTL__GIO6; + break; + + case 7: + i2c_addr = _fRW_MISCTL__GIO7; + break; + + case 8: + i2c_addr = _fRW_MISCTL__GIO8; + break; + + case 9: + i2c_addr = _fRW_MISCTL__GIO9; + break; + } + + gup_bit_write(i2c_addr, 1, 0); + + return 0; +} + +void gup_output_pulse(int t) +{ + unsigned long flags; + //s32 i; + + GTP_GPIO_OUTPUT(gtp_int_gpio, 0); + msleep(10); + + local_irq_save(flags); + + GTP_GPIO_OUTPUT(gtp_int_gpio, 1); + msleep(50); + GTP_GPIO_OUTPUT(gtp_int_gpio, 0); + msleep(t - 50); + GTP_GPIO_OUTPUT(gtp_int_gpio, 1); + + local_irq_restore(flags); + + msleep(20); + GTP_GPIO_OUTPUT(gtp_int_gpio, 0); +} + +static void gup_sys_clk_init(void) +{ + u8 buf; + + //_fRW_MISCTL__RG_RXADC_CKMUX = 0; + gup_bit_write(_rRW_MISCTL__ANA_RXADC_B0_, 5, 0); + //_bRW_MISCTL__RG_LDO_A18_PWD = 0; //DrvMISCTL_A18_PowerON + buf = 0; + i2c_write_bytes(i2c_connect_client, _bRW_MISCTL__RG_LDO_A18_PWD, &buf, 1); + //_bRW_MISCTL__RG_BG_PWD = 0; //DrvMISCTL_BG_PowerON + buf = 0; + i2c_write_bytes(i2c_connect_client, _bRW_MISCTL__RG_BG_PWD, &buf, 1); + //_bRW_MISCTL__RG_CLKGEN_PWD = 0; //DrvMISCTL_CLKGEN_PowerON + buf = 0; + i2c_write_bytes(i2c_connect_client, _bRW_MISCTL__RG_CLKGEN_PWD, &buf, 1); + //_fRW_MISCTL__RG_RXADC_PWD = 0; //DrvMISCTL_RX_ADC_PowerON + gup_bit_write(_rRW_MISCTL__ANA_RXADC_B0_, 0, 0); + //_fRW_MISCTL__RG_RXADC_REF_PWD = 0; //DrvMISCTL_RX_ADCREF_PowerON + gup_bit_write(_rRW_MISCTL__ANA_RXADC_B0_, 1, 0); + //gup_clk_dac_setting(60); + //_bRW_MISCTL__OSC_CK_SEL = 1;; + buf = 1; + i2c_write_bytes(i2c_connect_client, _bRW_MISCTL__OSC_CK_SEL, &buf, 1); +} + +s32 gup_clk_calibration(void) +{ + u8 buf; + //u8 trigger; + s32 i; + struct timeval start, end; + s32 count; + s32 count_ref; + s32 sec; + s32 usec; + //unsigned long flags; + struct goodix_ts_data *ts; + + buf = 0x0C; // hold ss51 and dsp + i2c_write_bytes(i2c_connect_client, _rRW_MISCTL__SWRST_B0_, &buf, 1); + + //_fRW_MISCTL__CLK_BIAS = 0; //disable clock bias + gup_bit_write(_rRW_MISCTL_RG_DMY83, 7, 0); + + //_fRW_MISCTL__GIO1_PU = 0; //set TOUCH INT PIN MODE as input + gup_bit_write(_rRW_MISCTL__GIO1CTL_B2_, 0, 0); + + //_fRW_MISCTL__GIO1_OE = 0; //set TOUCH INT PIN MODE as input + gup_bit_write(_rRW_MISCTL__GIO1CTL_B1_, 1, 0); + + //buf = 0x00; + //i2c_write_bytes(i2c_connect_client, _rRW_MISCTL__SWRST_B0_, &buf, 1); + //msleep(1000); + + GTP_INFO("CLK calibration GO"); + gup_sys_clk_init(); + gup_clk_calibration_pin_select(1);//use GIO1 to do the calibration + + GTP_GPIO_OUTPUT(gtp_int_gpio, 0); + + ts = i2c_get_clientdata(i2c_connect_client); + + for (i = INIT_CLK_DAC; i < MAX_CLK_DAC; i++) + { + GTP_INFO("CLK calibration DAC %d", i); + + if (ts->gtp_is_suspend) + { + i = 72; // 80; // if sleeping while calibrating main clock, set it default 72 + break; + } + + gup_clk_dac_setting(i); + gup_clk_count_init(1, CLK_AVG_TIME); + + #if 0 + gup_output_pulse(PULSE_LENGTH); + count = gup_clk_count_get(); + + if (count > PULSE_LENGTH * 60)//60= 60Mhz * 1us + { + break; + } + + #else + GTP_GPIO_OUTPUT(gtp_int_gpio, 0); + + //local_irq_save(flags); + do_gettimeofday(&start); + GTP_GPIO_OUTPUT(gtp_int_gpio, 1); + //local_irq_restore(flags); + + msleep(1); + GTP_GPIO_OUTPUT(gtp_int_gpio, 0); + msleep(1); + + //local_irq_save(flags); + do_gettimeofday(&end); + GTP_GPIO_OUTPUT(gtp_int_gpio, 1); + //local_irq_restore(flags); + + count = gup_clk_count_get(); + msleep(20); + GTP_GPIO_OUTPUT(gtp_int_gpio, 0); + + usec = end.tv_usec - start.tv_usec; + sec = end.tv_sec - start.tv_sec; + count_ref = 60 * (usec+ sec * MILLION);//60= 60Mhz * 1us + + GTP_DEBUG("== time %d, %d, %d", sec, usec, count_ref); + + if (count > count_ref) + { + GTP_DEBUG("== count_diff %d", count - count_ref); + break; + } + + #endif + } + + //clk_dac = i; + + gtp_reset_guitar(i2c_connect_client, 20); + +#if 0//for debug + //-- ouput clk to GPIO 4 + buf = 0x00; + i2c_write_bytes(i2c_connect_client, 0x41FA, &buf, 1); + buf = 0x00; + i2c_write_bytes(i2c_connect_client, 0x4104, &buf, 1); + buf = 0x00; + i2c_write_bytes(i2c_connect_client, 0x4105, &buf, 1); + buf = 0x00; + i2c_write_bytes(i2c_connect_client, 0x4106, &buf, 1); + buf = 0x01; + i2c_write_bytes(i2c_connect_client, 0x4107, &buf, 1); + buf = 0x06; + i2c_write_bytes(i2c_connect_client, 0x41F8, &buf, 1); + buf = 0x02; + i2c_write_bytes(i2c_connect_client, 0x41F9, &buf, 1); +#endif + + GTP_GPIO_AS_INT(gtp_int_gpio); + return i; +} + + + +s32 gup_hold_ss51_dsp(struct i2c_client *client) +{ + s32 ret = -1; + s32 retry = 0; + u8 rd_buf[3]; + + while(retry++ < 200) + { + // step4:Hold ss51 & dsp + ret = gup_set_ic_msg(client, _rRW_MISCTL__SWRST_B0_, 0x0C); + if(ret <= 0) + { + GTP_DEBUG("Hold ss51 & dsp I2C error,retry:%d", retry); + continue; + } + + // step5:Confirm hold + ret = gup_get_ic_msg(client, _rRW_MISCTL__SWRST_B0_, rd_buf, 1); + if (ret <= 0) + { + GTP_DEBUG("Hold ss51 & dsp I2C error,retry:%d", retry); + continue; + } + if (0x0C == rd_buf[GTP_ADDR_LENGTH]) + { + GTP_DEBUG("[enter_update_mode]Hold ss51 & dsp confirm SUCCESS"); + break; + } + GTP_DEBUG("Hold ss51 & dsp confirm 0x4180 failed,value:%d", rd_buf[GTP_ADDR_LENGTH]); + } + if(retry >= 200) + { + GTP_ERROR("Enter update Hold ss51 failed."); + return FAIL; + } + //DSP_CK and DSP_ALU_CK PowerOn + ret = gup_set_ic_msg(client, 0x4010, 0x00); + if (ret <= 0) + { + GTP_ERROR("[enter_update_mode]DSP_CK and DSP_ALU_CK PowerOn fail."); + return FAIL; + } + + //disable wdt + ret = gup_set_ic_msg(client, _bRW_MISCTL__TMR0_EN, 0x00); + + if (ret <= 0) + { + GTP_ERROR("[enter_update_mode]disable wdt fail."); + return FAIL; + } + + //clear cache enable + ret = gup_set_ic_msg(client, _bRW_MISCTL__CACHE_EN, 0x00); + + if (ret <= 0) + { + GTP_ERROR("[enter_update_mode]clear cache enable fail."); + return FAIL; + } + + //set boot from sram + ret = gup_set_ic_msg(client, _rRW_MISCTL__BOOTCTL_B0_, 0x02); + + if (ret <= 0) + { + GTP_ERROR("[enter_update_mode]set boot from sram fail."); + return FAIL; + } + + //software reboot + ret = gup_set_ic_msg(client, _bWO_MISCTL__CPU_SWRST_PULSE, 0x01); + if (ret <= 0) + { + GTP_ERROR("[enter_update_mode]software reboot fail."); + return FAIL; + } + + return SUCCESS; +} + +s32 gup_enter_update_mode_fl(struct i2c_client *client) +{ + s32 ret = -1; + //s32 retry = 0; + //u8 rd_buf[3]; + + //step1:RST output low last at least 2ms + GTP_GPIO_OUTPUT(gtp_rst_gpio, 0); + msleep(2); + + //step2:select I2C slave addr,INT:0--0xBA;1--0x28. + GTP_GPIO_OUTPUT(gtp_int_gpio, (client->addr == 0x14)); + msleep(2); + + //step3:RST output high reset guitar + GTP_GPIO_OUTPUT(gtp_rst_gpio, 1); + + msleep(5); + + //select addr & hold ss51_dsp + ret = gup_hold_ss51_dsp(client); + if (ret <= 0) + { + GTP_ERROR("[enter_update_mode]hold ss51 & dsp failed."); + return FAIL; + } + + //clear control flag + ret = gup_set_ic_msg(client, _rRW_MISCTL__BOOT_CTL_, 0x00); + + if (ret <= 0) + { + GTP_ERROR("[enter_update_mode]clear control flag fail."); + return FAIL; + } + + //set scramble + ret = gup_set_ic_msg(client, _rRW_MISCTL__BOOT_OPT_B0_, 0x00); + + if (ret <= 0) + { + GTP_ERROR("[enter_update_mode]set scramble fail."); + return FAIL; + } + + //enable accessing code + ret = gup_set_ic_msg(client, _bRW_MISCTL__MEM_CD_EN, 0x01); + + if (ret <= 0) + { + GTP_ERROR("[enter_update_mode]enable accessing code fail."); + return FAIL; + } + + return SUCCESS; +} + +static u8 gup_download_fw_dsp(struct i2c_client *client, u8 dwn_mode) +{ + s32 ret = 0; + + //step1:select bank2 + GTP_DEBUG("[download_fw_dsp]step1:select bank2"); + ret = gup_set_ic_msg(client, _bRW_MISCTL__SRAM_BANK, 0x02); + if (ret == FAIL) + { + GTP_ERROR("select bank 2 fail"); + return FAIL; + } + + if (GTP_FL_FW_BURN == dwn_mode) + { + GTP_INFO("[download_fw_dsp]Begin download dsp fw---->>"); + + if (ret <= 0) + { + GTP_ERROR("[download_fw_dsp]select bank2 fail."); + return FAIL; + } + GTP_DEBUG("burn fw dsp"); + ret = gup_burn_fw_proc(client, 0xC000, 2 * FW_DOWNLOAD_LENGTH, FW_DSP_LENGTH); // write the second ban + if (FAIL == ret) + { + GTP_ERROR("[download_fw_dsp]download FW dsp fail."); + return FAIL; + } + GTP_INFO("check firmware dsp"); + ret = gup_check_and_repair(client, 0xC000, 2 * FW_DOWNLOAD_LENGTH, FW_DSP_LENGTH); + if (FAIL == ret) + { + GTP_ERROR("check fw dsp failed!"); + return FAIL; + } + } + else if (GTP_FL_ESD_RECOVERY == dwn_mode) + { + GTP_INFO("[download_fw_dsp]Begin esd check dsp fw---->>"); + //GTP_INFO("esd recovery: check fw dsp"); + //ret = gup_check_and_repair(client, 0xC000, 2 * FW_DOWNLOAD_LENGTH, FW_DSP_LENGTH); + + //if(FAIL == ret) + { + //GTP_ERROR("[download_fw_dsp]Checked FW dsp fail, redownload fw dsp"); + GTP_INFO("esd recovery redownload firmware dsp code"); + ret = gup_burn_fw_proc(client, 0xC000, 2 * FW_DOWNLOAD_LENGTH, FW_DSP_LENGTH); + if (FAIL == ret) + { + GTP_ERROR("redownload fw dsp failed!"); + return FAIL; + } + } + } + else + { + GTP_INFO("check firmware dsp"); + ret = gup_check_and_repair(client, 0xC000, 2 * FW_DOWNLOAD_LENGTH, FW_DSP_LENGTH); + if (FAIL == ret) + { + GTP_ERROR("check fw dsp failed!"); + return FAIL; + } + } + return SUCCESS; +} + +static s32 gup_burn_fw_proc(struct i2c_client *client, u16 start_addr, s32 start_index, s32 burn_len) +{ + s32 ret = 0; + + GTP_DEBUG("burn firmware: 0x%04X, %d bytes, start_index: 0x%04X", start_addr, burn_len, start_index); + + ret = i2c_write_bytes(client, start_addr, (u8*)>p_default_FW_fl[FW_HEAD_LENGTH + start_index], burn_len); + if (ret < 0) + { + GTP_ERROR("burn 0x%04X, %d bytes failed!", start_addr, burn_len); + return FAIL; + } + return SUCCESS; +} + +static s32 gup_check_and_repair(struct i2c_client *client, u16 start_addr, s32 start_index, s32 chk_len) +{ + s32 ret = 0; + s32 cmp_len = 0; + u16 cmp_addr = start_addr; + s32 i = 0; + s32 chked_times = 0; + u8 chk_fail = 0; + + GTP_DEBUG("check firmware: start 0x%04X, %d bytes", start_addr, chk_len); + while ((chk_len > 0) && (chked_times < GTP_CHK_FW_MAX)) + { + if (chk_len >= GUP_FW_CHK_SIZE) + { + cmp_len = GUP_FW_CHK_SIZE; + } + else + { + cmp_len = chk_len; + } + ret = i2c_read_bytes(client, cmp_addr, chk_cmp_buf, cmp_len); + if (ret < 0) + { + chk_fail = 1; + break; + } + for (i = 0; i < cmp_len; ++i) + { + if (chk_cmp_buf[i] != gtp_default_FW_fl[FW_HEAD_LENGTH + start_index +i]) + { + chk_fail = 1; + i2c_write_bytes(client, cmp_addr+i, >p_default_FW_fl[FW_HEAD_LENGTH + start_index + i], cmp_len-i); + GTP_ERROR("Check failed index: %d(%d != %d), redownload chuck", i, chk_cmp_buf[i], + gtp_default_FW_fl[FW_HEAD_LENGTH + start_index +i]); + break; + } + } + if (chk_fail == 1) + { + chk_fail = 0; + chked_times++; + } + else + { + cmp_addr += cmp_len; + start_index += cmp_len; + chk_len -= cmp_len; + } + } + if (chk_len > 0) + { + GTP_ERROR("cmp_addr: 0x%04X, start_index: 0x%02X, chk_len: 0x%04X", cmp_addr, + start_index, chk_len); + return FAIL; + } + return SUCCESS; +} + +static u8 gup_download_fw_ss51(struct i2c_client *client, u8 dwn_mode) +{ + s32 section = 0; + s32 ret = 0; + s32 start_index = 0; + u8 bank = 0; + u16 burn_addr = 0xC000; + + if (GTP_FL_FW_BURN == dwn_mode) + { + GTP_INFO("download firmware ss51"); + } + else + { + GTP_INFO("check firmware ss51"); + } + for (section = 1; section <= 4; section += 2) + { + switch (section) + { + case 1: + bank = 0x00; + burn_addr = (section - 1) * FW_SS51_SECTION_LEN + 0xC000; + break; + case 3: + bank = 0x01; + burn_addr = (section - 3) * FW_SS51_SECTION_LEN + 0xC000; + break; + } + start_index = (section - 1) * FW_SS51_SECTION_LEN; + + GTP_DEBUG("download firmware ss51: select bank%d", bank); + ret = gup_set_ic_msg(client, _bRW_MISCTL__SRAM_BANK, bank); + if (GTP_FL_FW_BURN == dwn_mode) + { + GTP_DEBUG("download firmware ss51 section%d & %d", section, section+1); + ret = gup_burn_fw_proc(client, burn_addr, start_index, 2 * FW_SS51_SECTION_LEN); + if (ret == FAIL) + { + GTP_ERROR("download fw ss51 section%d & %d failed!", section, section+1); + return FAIL; + } + GTP_DEBUG("check firmware ss51 section%d & %d", section, section+1); + ret = gup_check_and_repair(client, burn_addr, start_index, 2 * FW_SS51_SECTION_LEN); + if (ret == FAIL) + { + GTP_ERROR("check ss51 section%d & %d failed!", section, section+1); + return FAIL; + } + } + else if (GTP_FL_ESD_RECOVERY == dwn_mode)// esd recovery mode + { + // GTP_INFO("esd recovery check ss51 section%d & %d", section, section+1); + // ret = gup_check_and_repair(client, burn_addr, start_index, FW_SS51_SECTION_LEN); + // if (ret == FAIL) + { + // GTP_ERROR("check ss51 section%d failed, redownload section%d", section, section); + GTP_DEBUG("esd recovery redownload ss51 section%d & %d", section, section+1); + ret = gup_burn_fw_proc(client, burn_addr, start_index, 2 * FW_SS51_SECTION_LEN); + if (ret == FAIL) + { + GTP_ERROR("download fw ss51 section%d failed!", section); + return FAIL; + } + } + } + else + { + GTP_DEBUG("check firmware ss51 section%d & %d", section, section+1); + ret = gup_check_and_repair(client, burn_addr, start_index, 2 * FW_SS51_SECTION_LEN); + if (ret == FAIL) + { + GTP_ERROR("check ss51 section%d & %d failed!", section, section+1); + return FAIL; + } + } + } + + return SUCCESS; +} + + +static s32 gup_prepare_fl_fw(char *path, st_fw_head *fw_head) +{ + s32 ret = 0; + s32 i = 0; + s32 timeout = 0; + struct goodix_ts_data *ts = i2c_get_clientdata(i2c_connect_client); + + if (!memcmp(path, "update", 6)) + { + GTP_INFO("Search for GT9XXF firmware file to update"); + + searching_file = 1; + for (i = 0; i < GUP_SEARCH_FILE_TIMES; ++i) + { + if (0 == searching_file) + { + GTP_INFO("Force terminate auto update for GT9XXF..."); + return FAIL; + } + GTP_DEBUG("Search for %s, %s for fw update.(%d/%d)", FL_UPDATE_PATH, FL_UPDATE_PATH_SD, i+1, GUP_SEARCH_FILE_TIMES); + update_msg.file = filp_open(FL_UPDATE_PATH, O_RDONLY, 0); + if (IS_ERR(update_msg.file)) + { + update_msg.file = filp_open(FL_UPDATE_PATH_SD, O_RDONLY, 0); + if (IS_ERR(update_msg.file)) + { + msleep(3000); + continue; + } + else + { + path = FL_UPDATE_PATH_SD; + break; + } + } + else + { + path = FL_UPDATE_PATH; + break; + } + } + searching_file = 0; + if (i == 50) + { + GTP_INFO("Search timeout, update aborted"); + return FAIL; + } + else + { + GTP_INFO("GT9XXF firmware file %s found!", path); + _CLOSE_FILE(update_msg.file); + } + while (ts->rqst_processing && (timeout++ < 5)) + { + GTP_DEBUG("request processing, waiting for accomplishment"); + msleep(1000); + } + } + GTP_INFO("Firmware update file path: %s", path); + + update_msg.file = filp_open(path, O_RDONLY, 0); + + if (IS_ERR(update_msg.file)) + { + GTP_ERROR("Open update file(%s) error!", path); + return FAIL; + } + + update_msg.old_fs = get_fs(); + set_fs(KERNEL_DS); + + update_msg.file->f_op->llseek(update_msg.file, 0, SEEK_SET); + update_msg.fw_total_len = update_msg.file->f_op->llseek(update_msg.file, 0, SEEK_END); + + update_msg.force_update = 0xBE; // GT9XXF ignore the 0xBE + if (update_msg.fw_total_len != sizeof(gtp_default_FW_fl)) + { + GTP_ERROR("Inconsistent fw size. default size: %d(%dK), file size: %d(%dK)", sizeof(gtp_default_FW_fl), sizeof(gtp_default_FW_fl)/1024, update_msg.fw_total_len, update_msg.fw_total_len/1024); + set_fs(update_msg.old_fs); + _CLOSE_FILE(update_msg.file); + return FAIL; + } + + update_msg.fw_total_len -= FW_HEAD_LENGTH; + GTP_DEBUG("Fimrware size: %d(%dK)", update_msg.fw_total_len, update_msg.fw_total_len / 1024); + + update_msg.file->f_op->llseek(update_msg.file, 0, SEEK_SET); + ret = update_msg.file->f_op->read(update_msg.file, (char*)gtp_default_FW_fl, + update_msg.fw_total_len + FW_HEAD_LENGTH, + &update_msg.file->f_pos); + update_msg.fw_total_len += FW_HEAD_LENGTH; + set_fs(update_msg.old_fs); + _CLOSE_FILE(update_msg.file); + + if (ret < 0) + { + GTP_ERROR("read %s failed, err-code: %d", path, ret); + return FAIL; + } + return SUCCESS; +} +static u8 gup_check_update_file_fl(struct i2c_client *client, st_fw_head* fw_head, char* path) +{ + s32 ret = 0; + s32 i = 0; + s32 fw_checksum = 0; + + if (NULL != path) + { + ret = gup_prepare_fl_fw(path, fw_head); + if (FAIL == ret) + { + return FAIL; + } + } + else + { + update_msg.fw_total_len = sizeof(gtp_default_FW_fl); + } + + memcpy(fw_head, gtp_default_FW_fl, FW_HEAD_LENGTH); + GTP_INFO("FILE HARDWARE INFO: %02x%02x%02x%02x", fw_head->hw_info[0], fw_head->hw_info[1], fw_head->hw_info[2], fw_head->hw_info[3]); + GTP_INFO("FILE PID: %s", fw_head->pid); + fw_head->vid = ((fw_head->vid & 0xFF00) >> 8) + ((fw_head->vid & 0x00FF) << 8); + GTP_INFO("FILE VID: %04x", fw_head->vid); + + //check firmware legality + fw_checksum = 0; + for(i = FW_HEAD_LENGTH; i < update_msg.fw_total_len; i += 2) + { + fw_checksum += (gtp_default_FW_fl[i] << 8) + gtp_default_FW_fl[i+1]; + } + ret = SUCCESS; + + GTP_DEBUG("firmware checksum: %x", fw_checksum&0xFFFF); + if (fw_checksum & 0xFFFF) + { + GTP_ERROR("Illegal firmware file."); + ret = FAIL; + } + + return ret; +} + +s32 gup_fw_download_proc(void *dir, u8 dwn_mode) +{ + s32 ret = 0; + u8 retry = 0; + st_fw_head fw_head; + struct goodix_ts_data *ts; + + ts = i2c_get_clientdata(i2c_connect_client); + if (NULL == dir) + { + if(GTP_FL_FW_BURN == dwn_mode) // GT9XXF firmware burn mode + { + GTP_INFO("[fw_download_proc]Begin fw download ......"); + } + else if (GTP_FL_ESD_RECOVERY == dwn_mode) // GTP_FL_ESD_RECOVERY: GT9XXF esd recovery mode + { + GTP_INFO("[fw_download_proc]Begin fw esd recovery check ......"); + } + else + { + GTP_INFO("[fw_download_proc]Being fw repair check......"); + } + } + else + { + GTP_INFO("[fw_download_proc]Begin firmware update by bin file"); + } + + total_len = 100; + show_len = 0; + + ret = gup_check_update_file_fl(i2c_connect_client, &fw_head, (char *)dir); + show_len = 10; + + if (FAIL == ret) + { + GTP_ERROR("[fw_download_proc]check update file fail."); + goto file_fail; + } + + if (!memcmp(fw_head.pid, "950", 3)) + { + ts->is_950 = 1; + GTP_DEBUG("GT9XXF Ic Type: gt950"); + } + else + { + ts->is_950 = 0; + } + + if (NULL != dir) + { + gtp_irq_disable(ts); +#if GTP_ESD_PROTECT + gtp_esd_switch(ts->client, SWITCH_OFF); +#endif + } + + ret = gup_enter_update_mode_fl(i2c_connect_client); + show_len = 20; + if (FAIL == ret) + { + GTP_ERROR("[fw_download_proc]enter update mode fail."); + goto download_fail; + } + + while (retry++ < 5) + { + ret = gup_download_fw_ss51(i2c_connect_client, dwn_mode); + show_len = 60; + if (FAIL == ret) + { + GTP_ERROR("[fw_download_proc]burn ss51 firmware fail."); + continue; + } + + ret = gup_download_fw_dsp(i2c_connect_client, dwn_mode); + show_len = 80; + if (FAIL == ret) + { + GTP_ERROR("[fw_download_proc]burn dsp firmware fail."); + continue; + } + + GTP_INFO("[fw_download_proc]UPDATE SUCCESS."); + break; + } + + if (retry >= 5) + { + GTP_ERROR("[fw_download_proc]retry timeout,UPDATE FAIL."); + goto download_fail; + } + + if (NULL != dir) + { + gtp_irq_enable(ts); + gtp_fw_startup(ts->client); + #if GTP_ESD_PROTECT + gtp_esd_switch(ts->client, SWITCH_ON); + #endif + } + show_len = 100; + return SUCCESS; + +download_fail: + if (NULL != dir) + { + gtp_irq_enable(ts); + gtp_fw_startup(ts->client); + #if GTP_ESD_PROTECT + gtp_esd_switch(ts->client, SWITCH_ON); + #endif + } +file_fail: + show_len = 200; + + return FAIL; +} + +#endif + +//**************** For GT9XXF End ********************// diff --git a/drivers/input/touchscreen/vim3-ft5x06.c b/drivers/input/touchscreen/vim3-ft5x06.c index c6c28a1d8a5f1..a8720bf3b5a10 100755 --- a/drivers/input/touchscreen/vim3-ft5x06.c +++ b/drivers/input/touchscreen/vim3-ft5x06.c @@ -776,6 +776,7 @@ static int edt_ft5x06_ts_identify(struct i2c_client *client, * to have garbage in there */ memset(rdbuf, 0, sizeof(rdbuf)); + udelay(50); error = edt_ft5x06_ts_readwrite(client, 1, "\xbb", EDT_NAME_LEN - 1, rdbuf); if (error)